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

Prayer

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

fork, wait, system

Posted on 2009-09-28 13:53 Prayer 閱讀(1238) 評論(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>
            美日韩精品免费| 国产欧美韩国高清| 噜噜噜久久亚洲精品国产品小说| 欧美极品aⅴ影院| 在线观看欧美日韩国产| 亚洲一区二区三区免费观看| 欧美黑人一区二区三区| 久久爱另类一区二区小说| 国产精品中文在线| 欧美自拍偷拍| 性色一区二区| 久久尤物视频| 尤物yw午夜国产精品视频明星| 亚洲欧洲av一区二区三区久久| 99pao成人国产永久免费视频| 欧美激情一区二区| 亚洲免费高清视频| 亚洲日韩欧美一区二区在线| 久久精品国内一区二区三区| 国产一区二区三区在线免费观看| 欧美亚洲一区三区| 午夜电影亚洲| 在线播放日韩专区| 亚洲第一网站| 欧美三级日本三级少妇99| 一区二区三区日韩| 这里只有精品视频在线| 国产精品永久| 蜜桃av噜噜一区二区三区| 美脚丝袜一区二区三区在线观看| 亚洲国产你懂的| 日韩系列在线| 国产一区二区三区久久| 夜夜狂射影院欧美极品| 黄色成人精品网站| 欧美成人首页| 欧美日韩一区在线播放| 国产亚洲aⅴaaaaaa毛片| 久久久久久久综合狠狠综合| 久久er精品视频| 亚洲日本在线观看| 亚洲一级片在线看| 在线免费不卡视频| 99精品福利视频| 国模精品一区二区三区| 91久久在线视频| 国产欧美日韩另类一区| 欧美国产视频在线| 国产精品久久久久aaaa樱花| 久久伊人一区二区| 国产精品二区二区三区| 性色一区二区三区| 亚洲精品乱码久久久久久按摩观| 亚洲视频1区| 亚洲欧洲精品一区二区三区不卡 | 国产性色一区二区| 欧美成人官网二区| 老司机精品视频网站| 亚洲欧美另类在线| 欧美www视频| 久久成人18免费观看| 欧美精品色网| 久久久久久国产精品一区| 美脚丝袜一区二区三区在线观看 | 欧美日韩在线精品一区二区三区| 午夜精品免费在线| 欧美成人免费在线观看| 欧美一区二区精品| 欧美片在线播放| 欧美国产日韩一区| 一区二区亚洲精品国产| 亚洲综合色婷婷| 这里只有视频精品| 欧美国产另类| 欧美激情导航| 亚洲电影在线看| 欧美尤物巨大精品爽| 亚洲男人的天堂在线aⅴ视频| 久久中文久久字幕| 久久久久久久欧美精品| 欧美片第一页| 欧美激情在线观看| 激情久久久久| 久久精品国产亚洲a| 久久se精品一区精品二区| 国产精品久久99| 99精品视频一区| 一区二区三区日韩精品| 欧美猛交免费看| 亚洲精品少妇| 亚洲天堂网在线观看| 欧美日本一区二区三区| 亚洲精选视频在线| 亚洲一区二区不卡免费| 欧美涩涩网站| 在线视频欧美精品| 久久蜜桃精品| 夜夜嗨av一区二区三区网页| 亚洲国产毛片完整版| 久久久久久久久一区二区| 久久久高清一区二区三区| 国产精品一区二区久久精品| 午夜精品久久久久久| 激情综合网址| 久久岛国电影| 欧美**字幕| 日韩视频精品在线| 欧美午夜视频一区二区| 亚洲影院一区| 久久青草福利网站| 亚洲丁香婷深爱综合| 欧美激情一区二区三区高清视频| 91久久久久久国产精品| 久久精选视频| 久久久精品国产一区二区三区 | 一区二区三区久久精品| 亚洲欧美视频在线观看视频| 国产婷婷一区二区| 美女精品在线| 一区二区三区黄色| 久久免费精品日本久久中文字幕| 在线免费观看欧美| 欧美黄网免费在线观看| 亚洲少妇中出一区| 久久久在线视频| 日韩一级在线观看| 国产欧美日韩不卡免费| 免费视频一区| 性久久久久久久久久久久| 亚洲高清免费在线| 久久国产精品99精品国产| 亚洲黄色免费电影| 亚洲一区二区三区成人在线视频精品| 亚洲理伦在线| 久久激情综合网| 亚洲精品资源| 欧美高清视频一区二区三区在线观看 | 亚洲一区二区三区在线| 国产一区二区日韩精品| 欧美aaa级| 亚洲欧美日韩国产| 亚洲国产精品久久久久婷婷884| 宅男噜噜噜66一区二区| 国外成人性视频| 国产精品久久久久aaaa| 欧美va天堂| 久久久精品2019中文字幕神马| 99精品视频免费观看| 久久精品综合网| 亚洲一区二区三区中文字幕 | 久久久久九九九| 亚洲最快最全在线视频| 亚洲欧美自拍偷拍| 国精品一区二区| 国产精品99一区| 欧美成人免费大片| 久久精视频免费在线久久完整在线看| 国产精品99久久久久久白浆小说| 欧美国产极速在线| 久久一区二区三区四区| 国产亚洲一区二区三区在线播放| 欧美视频亚洲视频| 欧美激情一二三区| 美女视频黄 久久| 久久―日本道色综合久久| 久久本道综合色狠狠五月| 午夜精品三级视频福利| 亚洲视频久久| 一区二区三区欧美成人| 99视频精品免费观看| 99国产精品视频免费观看| 日韩一区二区精品在线观看| 亚洲理论电影网| 亚洲视频一区二区在线观看 | 欧美一区免费| 欧美一区二区三区久久精品茉莉花| 一本大道久久a久久精品综合| 亚洲靠逼com| 一区二区三区高清在线观看| 日韩天堂在线观看| 在线亚洲欧美专区二区| 亚洲欧洲日韩综合二区| 欧美亚洲免费高清在线观看| 亚洲一级片在线看| 亚洲一区二区在线免费观看视频| 99国产精品视频免费观看一公开 | 欧美在线在线| 香蕉av777xxx色综合一区| 午夜伦理片一区| 欧美在线日韩在线| 久久高清国产| 美女脱光内衣内裤视频久久影院 | 99精品国产高清一区二区| 99ri日韩精品视频| 久久精品一二三| 久久久www成人免费精品| 麻豆精品视频在线观看| 欧美精品一区二| 国产欧美va欧美va香蕉在| 激情综合中文娱乐网|