青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

fork, wait, system

Posted on 2009-09-28 13:53 Prayer 閱讀(1239) 評論(0)  編輯 收藏 引用 所屬分類: LINUX/UNIX/AIX

fork,vfork


#include <unistd.h>;
#include <sys/types.h>;

main ()
{
        pid_t pid;
        pid=fork();

        if (pid < 0)
                printf("error in fork!");
        else if (pid == 0)
                printf("i am the child process, my process id is %d\n",getpid());
        else
                printf("i am the parent process, my process id is %d\n",getpid());
}
要搞清楚fork的執行過程,就必須先講清楚操作系統中的“進程(process)”概念。一個進程,主要包含三個元素:

o. 一個可以執行的程序;
o. 和該進程相關聯的全部數據(包括變量,內存空間,緩沖區等等);
o. 程序的執行上下文(execution context)。

不妨簡單理解為,一個進程表示的,就是一個可執行程序的一次執行過程中的一個狀態。操作系統對進程的管理,典型的情況,是通過進程表完成的。進程表中的每 一個表項,記錄的是當前操作系統中一個進程的情況。對于單 CPU的情況而言,每一特定時刻只有一個進程占用 CPU,但是系統中可能同時存在多個活動的(等待執行或繼續執行的)進程。

一個稱為“程序計數器(program counter, pc)”的寄存器,指出當前占用 CPU的進程要執行的下一條指令的位置。

當分給某個進程的 CPU時間已經用完,操作系統將該進程相關的寄存器的值,保存到該進程在進程表中對應的表項里面;把將要接替這個進程占用 CPU的那個進程的上下文,從進程表中讀出,并更新相應的寄存器(這個過程稱為“上下文交換(process context switch)”,實際的上下文交換需要涉及到更多的數據,那和fork無關,不再多說,主要要記住程序寄存器pc指出程序當前已經執行到哪里,是進程上 下文的重要內容,換出 CPU的進程要保存這個寄存器的值,換入CPU的進程,也要根據進程表中保存的本進程執行上下文信息,更新這個寄存器)。

好了,有這些概念打底,可以說fork了。當你的程序執行到下面的語句:
pid=fork();
操作系統創建一個新的進程(子進程),并且在進程表中相應為它建立一個新的表項。新進程和原有進程的可執行程序是同一個程序;上下文和數據,絕大部分就是 原進程(父進程)的拷貝,但它們是兩個相互獨立的進程!此時程序寄存器pc,在父、子進程的上下文中都聲稱,這個進程目前執行到fork調用即將返回(此 時子進程不占有CPU,子進程的pc不是真正保存在寄存器中,而是作為進程上下文保存在進程表中的對應表項內)。問題是怎么返回,在父子進程中就分道揚 鑣。

父進程繼續執行,操作系統對fork的實現,使這個調用在父進程中返回剛剛創建的子進程的pid(一個正整數),所以下面的if語句中pid<0, pid==0的兩個分支都不會執行。所以輸出i am the parent process...

子進程在之后的某個時候得到調度,它的上下文被換入,占據 CPU,操作系統對fork的實現,使得子進程中fork調用返回0。所以在這個進程(注意這不是父進程了哦,雖然是同一個程序,但是這是同一個程序的另 外一次執行,在操作系統中這次執行是由另外一個進程表示的,從執行的角度說和父進程相互獨立)中pid=0。這個進程繼續執行的過程中,if語句中 pid<0不滿足,但是pid==0是true。所以輸出i am the child process...

我想你比較困惑的就是,為什么看上去程序中互斥的兩個分支都被執行了。在一個程序的一次執行中,這當然是不可能的;但是你看到的兩行輸出是來自兩個進程,這兩個進程來自同一個程序的兩次執行。


#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
globa=6;
int main(void)
{
 var=88;
 pid_t result;
 result = fork();
//result = vfork();
 if(result == -1)
 {
  perror("fork");
  exit;
 }
 else if(result == 0)
 {
  globa++;
  var++;
  printf("The return value is %d\n In child process!!\n My PID is %d\n",result,getpid());
 }
 else
 {
  printf("The return value is %d\n In father process!!\n My PID is %d\n",result,getpid());
 }
 printf("PID=%d,globa=%d,var=%d",getpid(),globa,var);
}
程序運行結果如下:
(fork()運行結果)
The return value is 0
 In child process!!
 My PID is 3736
PID=3736,globa=7,var=89
The return value is 3736
 In father process!!
 My PID is 3735
PID=3735,globa=6,var=88
 
(vfork()運行結果)
The return value is 0
 In child process!!
 My PID is 3736
PID=3736,globa=7,var=89
The return value is 3736
 In father process!!
 My PID is 3735
PID=3735,globa=7,var=89
 
分析:首先分析fork與vfork函數的運行機制,拿fork為例,fork()并不是進程切換,而是復制一個當前進程。當使用pid= fork()時,其實是創建了兩個進程,這兩個進程有著相同的內容,例如變量的值,空間配,特別是正在執行的語句等等都相同,但這些內容卻在兩個獨立的內 存空間中。因此當執行上述代碼時,便相當于同一段代碼在兩個進程中執行,所有就出現了兩個結果,一個是子進程的信息,一個是父進程的信息。再看globa 和var這兩個變量,由于是兩個獨立的進程,因此當各自執行代碼時,變量也不會互相受到影響,所以在子進程中的globa和var均發生了變化,而在父進 程中卻沒有變化。
     其次分析一下,fork()和vfork()的區別:vfork采用寫時拷貝技術(write-on-copy),父進程與子進程享用同一個內存空間,因 此,程序中的變量其實也就是父子進程的公共變量,所以,當其中一個進程中的變量值發生改變時,另一個進程中的變量值肯定也跟著發生變化,另外,兩個函數的 區別還在于vfork用于創建一個新進程,而該新進程的目的是exec一個新進程,vfork和fork一樣都創建一個子進程,但是它并不將父進程的地址 空間完全復制到子進程中,因為子進程會立即調用exec,于是也就不會存放該地址空間。不過在子進程中調用exec或exit之前,他在父進程的空間中運 行。vfork保證子進程先運行,在她調用exec exit之后父進程才可能被調度運行。如果在調用這兩個函數之前子進程依賴于父進程的進一步動作,則會導致死鎖。 用fork函數創建子進程后,子進程往往要調用一種exec函數以執行另一個程序,當進程調用一種exec函數時,該進程完全由新程序代換,而新程序則從 其main函數開始執行,因為調用exec并不創建新進程,所以前后的進程id 并未改變,exec只是用另一個新程序替換了當前進程的正文,數據,堆和棧段。


wait(等待子進程中斷或結束)
相關函數 waitpid,fork
表頭文件
#include
#include
定義函數 pid_t wait (int * status);
函數說明
wait()會暫時停止目前進程的執行,直到有信號來到或子進程結
束。如果在調用wait()時子進程已經結束,則wait()會立即返
回子進程結束狀態值。子進程的結束狀態值會由參數status 返回,
而子進程的進程識別碼也會一快返回。如果不在意結束狀態值,則
參數status 可以設成NULL。子進程的結束狀態值請參考waitpid()。
返回值
如果執行成功則返回子進程識別碼(PID),如果有錯誤發生則返回
-1。失敗原因存于errno 中。
附加說明
范例
#include
#include
#include
#include
main()
{
pid_t pid;
int status,i;
if(fork()= =0){
printf(“This is the child process .pid =%d\n”,getpid());
exit(5);
}else{
sleep(1);
printf(“This is the parent process ,wait for child...\n”;
pid=wait(&status);
i=WEXITSTATUS(status);
printf(“child’s pid =%d .exit status=^d\n”,pid,i);
}
}
執行
This is the child process.pid=1501
This is the parent process .wait for child...
child’s pid =1501,exit status =5
waitpid(等待子進程中斷或結束)
相關函數 wait,fork
表頭文件
#include
#include
定義函數 pid_t waitpid(pid_t pid,int * status,int options);
函數說明
waitpid()會暫時停止目前進程的執行,直到有信號來到或子進程
結束。如果在調用wait()時子進程已經結束,則wait()會立即
返回子進程結束狀態值。子進程的結束狀態值會由參數status 返回,
而子進程的進程識別碼也會一快返回。如果不在意結束狀態值,則
參數status 可以設成NULL。參數pid 為欲等待的子進程識別碼,
其他數值意義如下:
pid0 等待任何子進程識別碼為pid 的子進程。
參數option 可以為0 或下面的OR 組合:
WNOHANG 如果沒有任何已經結束的子進程則馬上返回,不予以
等待。
WUNTRACED 如果子進程進入暫停執行情況則馬上返回,但結束
狀態不予以理會。
子進程的結束狀態返回后存于status,底下有幾個宏可判別結束情
況:
WIFEXITED(status)如果子進程正常結束則為非0 值。
WEXITSTATUS(status)取得子進程exit()返回的結束代碼,一
般會先用WIFEXITED 來判斷是否正常結束才能使用此宏。
WIFSIGNALED(status)如果子進程是因為信號而結束則此宏值為

WTERMSIG(status) 取得子進程因信號而中止的信號代碼,一般
會先用WIFSIGNALED 來判斷后才使用此宏。
WIFSTOPPED(status) 如果子進程處于暫停執行情況則此宏值為
真。一般只有使用WUNTRACED 時才會有此情況。
WSTOPSIG(status) 取得引發子進程暫停的信號代碼,一般會先
用WIFSTOPPED 來判斷后才使用此宏。
返回值
如果執行成功則返回子進程識別碼(PID),如果有錯誤發生則返回
-1。失敗原因存于errno 中。
范例
參考wait()。

inux的system () 函數詳解
 
 
system(執行shell 命令)
相關函數
        fork,execve,waitpid,popen
表頭文件
        #i nclude<stdlib.h>
定義函數
        int system(const char * string);
函數說明
        system()會調用fork()產生子進程,由子進程來調用/bin/sh-c string來執行參數string字符串所代表的命令,此命>令執行完后隨即返回原調用的進程。在調用system()期間SIGCHLD 信號會被暫時擱置,SIGINT和SIGQUIT 信號則會被忽略。
返回值
  =-1:出現錯誤  
  =0:調用成功但是沒有出現子進程  
  >0:成功退出的子進程的id
        如果system()在調用/bin/sh時失敗則返回127,其他失敗原因返回-1。若參數string為空指針(NULL),則返回非零值>。 如果system()調用成功則最后會返回執行shell命令后的返回值,但是此返回值也有可能為 system()調用/bin/sh失敗所返回的127,因此最好能再檢查errno 來確認執行成功。
附加說明
        在編寫具有SUID/SGID權限的程序時請勿使用system(),system()會繼承環境變量,通過環境變量可能會造成系統安全的問題。
范例
        #i nclude<stdlib.h>
main()
{
system(“ls -al /etc/passwd /etc/shadow”);
}
執行結果:

-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
-r--------- 1 root root 572 Sep 2 15 :34 /etc/shado

例2:

char tmp[];
sprintf(tmp,"/bin/mount -t vfat %s /mnt/usb",dev);
system(tmp);
其中dev是/dev/sda1。
 


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/alentam/archive/2008/04/09/2270763.aspx

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            美国十次成人| 最新日韩精品| 久久精品国产综合精品| 欧美1区2区视频| 老牛影视一区二区三区| 国产欧美综合一区二区三区| 亚洲精品一区中文| 亚洲乱码久久| 亚洲人成免费| 一区二区三区亚洲| 影音欧美亚洲| 免费一级欧美片在线观看| 久久先锋资源| 欧美久久久久久久久久| 久久久久久电影| 欧美电影免费观看高清完整版| 六月婷婷久久| 午夜精品视频一区| 亚洲国产成人91精品| 国产精品久久久久久福利一牛影视| 性欧美1819sex性高清| 久久国产手机看片| 一区二区三区欧美在线| 亚洲国产专区校园欧美| 欧美视频一区二区在线观看| 蜜乳av另类精品一区二区| 宅男精品视频| 一区二区三区黄色| 国产一区白浆| 欧美日韩精品在线播放| 久久久久久夜| 久久久久久久一区| 亚洲综合大片69999| 亚洲美女视频在线观看| 亚洲一区二区在线播放| 亚洲一区二区影院| 亚洲国产精品成人综合色在线婷婷| 欧美一区二区在线观看| 裸体歌舞表演一区二区| 久久婷婷综合激情| 国语自产精品视频在线看| 欧美成人久久| 美女主播精品视频一二三四| 欧美大片一区二区| 亚洲成人资源| 久久精品亚洲一区二区三区浴池| 免费观看国产成人| 久久蜜桃香蕉精品一区二区三区| 亚洲欧美综合v| 欧美日韩亚洲一区二区| 亚洲激情成人在线| 亚洲一区二区三区777| 亚洲一区在线观看免费观看电影高清| 野花国产精品入口| 国内偷自视频区视频综合| 在线国产精品播放| 亚洲福利久久| 欧美一区免费| 亚洲一区欧美激情| 欧美高清视频在线播放| 欧美日韩免费高清一区色橹橹| 国产欧美日韩一区| 亚洲欧美国产高清va在线播| 欧美大香线蕉线伊人久久国产精品| 亚洲国产综合在线| 亚洲精品少妇| 日韩视频永久免费观看| 亚洲精品亚洲人成人网| 亚洲国产毛片完整版| 在线综合亚洲欧美在线视频| 国产日韩亚洲欧美| 欧美巨乳波霸| 久久久久久夜精品精品免费| 亚洲视频在线一区| 亚洲国产99精品国自产| 久久精品国产欧美激情| 亚洲无亚洲人成网站77777| 亚洲国产一二三| 国产在线精品一区二区夜色| 欧美日韩亚洲一区二区三区| 欧美大片免费观看| 久久夜色精品国产亚洲aⅴ| 亚洲欧美文学| 亚洲一级黄色| 一区二区国产在线观看| 亚洲日本一区二区| 亚洲韩国青草视频| 欧美激情亚洲| 欧美激情第8页| 欧美激情精品久久久六区热门 | 99热在线精品观看| 91久久一区二区| 亚洲国产精品ⅴa在线观看| 欧美成人日本| 久热爱精品视频线路一| 另类av一区二区| 美日韩精品免费| 免播放器亚洲一区| 欧美 日韩 国产一区二区在线视频| 久久天天躁夜夜躁狠狠躁2022| 久久精品视频亚洲| 国产精品jvid在线观看蜜臀| 亚洲精品乱码久久久久久按摩观| 国产一区99| 亚洲国产精品福利| 欧美国产综合视频| 欧美国产视频在线观看| 欧美黑人在线观看| 欧美国产日韩一区二区| 亚洲天堂av在线免费| 中文亚洲欧美| 久久亚洲精品欧美| 欧美视频1区| 精品成人在线观看| 99日韩精品| 久久久精品一区二区三区| 欧美国产精品| 亚洲女人天堂av| 久久久美女艺术照精彩视频福利播放| 欧美日韩亚洲免费| 欧美精品一区二区蜜臀亚洲 | 91久久国产综合久久91精品网站| 亚洲乱码日产精品bd| 久久精品卡一| 欧美精品日韩一本| 狠狠干综合网| 91久久综合亚洲鲁鲁五月天| 久久国产精品亚洲77777| 亚洲精品乱码视频| 久久精品二区亚洲w码| 亚洲美女色禁图| 欧美在线看片a免费观看| 国产精品99免费看 | 久久精品视频va| 国产精品日韩一区二区| 亚洲日本一区二区| 久久亚洲影音av资源网| 久久青草欧美一区二区三区| 亚洲小视频在线观看| 久久久久久午夜| 国产午夜久久| 亚洲欧美三级伦理| 亚洲国产成人精品久久| 久久蜜桃av一区精品变态类天堂| 国产精品不卡在线| 一区二区三区高清在线观看| 一本大道久久a久久精二百| 一区二区欧美在线| 久久久天天操| 国产在线高清精品| 在线一区二区日韩| 亚洲精品美女在线观看播放| 久久狠狠婷婷| 黄色国产精品一区二区三区| 亚洲欧美在线观看| 亚洲乱码国产乱码精品精| 久热精品视频在线观看一区| 国产伦精品一区二区| 日韩一级大片| 亚洲精品国产品国语在线app| 亚洲一区二区三区精品在线观看| 欧美日韩午夜| 久久久夜夜夜| 亚洲电影免费观看高清完整版在线观看| 久久久91精品国产| 亚洲视频每日更新| 欧美视频一区二区| 中国av一区| 亚洲色诱最新| 欧美日韩在线一区二区三区| 亚洲色图在线视频| 日韩视频欧美视频| 国产精品高潮呻吟| 一本色道久久加勒比88综合| 日韩一级成人av| 亚洲制服欧美中文字幕中文字幕| 欧美三级电影网| 亚洲在线播放| 亚洲一级在线观看| 国产午夜久久| 久久亚洲国产精品日日av夜夜| 久久激情中文| 国产亚洲精品久久久久久| 久久综合九色九九| 最新中文字幕亚洲| 欧美激情四色| 亚洲欧美日韩国产综合| 亚洲一区二区三区在线看| 国产一区二区三区高清播放| 久久精品视频播放| 麻豆乱码国产一区二区三区| 在线观看日韩专区| 亚洲精品一二区| 亚洲国产成人精品久久久国产成人一区| 欧美天天影院| 亚洲砖区区免费| 久久国产精品一区二区三区四区| 在线观看三级视频欧美| 亚洲国产精品va在线看黑人| 欧美色欧美亚洲高清在线视频|