1、fork後子進程從哪裡開始執行
(代碼驗證) fork確實創建了一個子進程並完全復制父進程,但是子進程是從fork後面那個指令開始執行的。對於原因也很合邏輯,如果子進程也從main開頭到尾執行所有指令,那它執行到fork指令時也必定會創建一個子子進程,如此下去這個小小的程序就可以創建無數多個進程可以把你的電腦搞癱瘓,所以fork作者肯定不會傻到這種程度fork和線程,進程的理解2011-10-11 10:09 本文分為三部分:1. 什麼是fork?2. fork用途?3. fork怎麼工作? 1. 什麼是fork?Fork源於OS中多線程任務的需要。在傳統的Unix環境下,有兩個基本的操作用於創建和修改進程:函數fork( )用來創建一個新的進程,該進程幾乎是當前進程的一個完全拷貝;函數族exec( )用來啟動另外的進程以取代當前運行的進程。下面說一下進程和線程。進程的簡單理解就是:一個進程表示的就是一個可執行程序的一次執行過程中的一個狀態。一個進程,主要包含三個元素:一個可以執行的程序; --- 代碼段和該進程相關聯的全部數據(包括變數,內存空間,緩沖區等等); --- 數據段程序的執行上下文(execution context)。 --- 堆棧段 "代碼段",顧名思義,就是存放了程序代碼的數據,假如機器中有數個進程運行相同的一個程序,那麼它們就可以使用相同的代碼段。"堆棧段"存放的就是子程序的返回地址、子程序的參數以及程序的局部變數。而數據段則存放程序的全局變數,常數以及動態數據分配的數據空間(比如用malloc之類的函數取得的空間)。 一般的CPU都有上述三種段寄存器,以方便操作系統的運行。這三個部分也是構成一個完整的執行序列的必要的部分。系統如果同時運行數個相同的程序,它們之間就不能使用同一個堆棧段和數據段。 操作系統對進程管理,最典型的是通過進程表完成的。進程表裡再通過一個稱為「程序計數器(program counter, pc)」的寄存器來完成「上下文的切換」。(實際的上下文交換需要涉及到更多的數據,和fork無關,不再多說,PC主要用於指出程序當前已經執行到哪裡,是進程上下文的重要內容,換出CPU的進程要保存這個寄存器的值,換入CPU的進程,也要根據進程表中保存的本進程執行上下文信息,更新這個寄存器)。 進程表中的每一個表項,記錄的是當前操作系統中一個進程的情況。對於單 CPU的情況而言,每一特定時刻只有一個進程佔用 CPU,但是系統中可能同時存在多個活動的(等待執行或繼續執行的)進程。PC用於指出當前佔用 CPU的進程要執行的下一條指令的位置。 當分給某個進程的 CPU時間已經用完,操作系統將該進程相關的寄存器的值,保存到該進程在進程表中對應的表項裡面;把將要接替這個進程佔用 CPU的那個進程的上下文,從進程表中讀出,並更新相應的寄存器(這個過程稱為「上下文交換(process context switch)」 下面繼續說fork了。當程序執行到下面的語句:pid=fork(); 操作系統創建一個新的進程(子進程),並且在進程表中相應為它建立一個新的表項。新進程和原有進程的可執行程序是同一個程序;上下文和數據,絕大部分就是原進程(父進程)的拷貝,但它們是兩個相互獨立的進程!此時程序寄存器pc,在父、子進程的上下文中都聲稱,這個進程目前執行到fork調用即將返回(此時子進程不佔有CPU,子進程的pc不是真正保存在寄存器中,而是作為進程上下文保存在進程表中的對應表項內)。問題是怎麼返回。它們的返回順序是不確定的,取決於OS內的調度。如果想明確它們的執行順序,就得實現「同步」,或者是使用vfork()。這里假設父進程繼續執行,操作系統對fork的實現,使這個調用在父進程中返回剛剛創建的子進程的pid(一個正整數),所以下面的if語句中pid<0, pid==0的兩個分支都不會執行。所以一般執行fork後都會有兩個輸出。 2. Fork用途歸結起來有兩個:第一, 一個進程希望復制自身,從而父子進程能執行不同代碼段。第二, 進程想執行另外一個程序歸結起來說就是實現多線程。C語言多線程實現需要自己控制來實現,這個比JAVA要復雜。 3. Fork怎麼工作?先看一個例子:#include <unistd.h>;#include <sys/types.h>;int main (){ pid_t pid; pid=fork(); // 1)從這里開始程序分岔,父子進程都從這一句開始執行一次 if (pid < 0) printf("error!"); else if (pid == 0) printf("child process, process id is %dn", getpid()); else // pid > 0 printf("parent process, process id is %dn",getpid());return 0;}結果:[root@localhost yezi]# ./a.outparent process, process id is 4285 對於上面程序段有以下幾個關鍵點: (1)返回值的問題:正確返回:父進程中返回子進程的pid,因此> 0;子進程返回0錯誤返回:-1 子進程是父進程的一個拷貝。即,子進程從父進程得到了數據段和堆棧段的拷貝,這些需要分配新的內存;而對於只讀的代碼段,通常使用共享內存的方式訪問。父進程與子進程的不同之處在於:fork的返回值不同——父進程中的返回值為子進程的進程號,而子進程為0。只有父進程執行的getpid()才是他自己的進程號。對子進程來說,fork返回給它0,但它的pid絕對不會是0;之所以fork返回0給它,是因為它隨時可以調用getpid()來獲取自己的pid; (2) fork返回後,子進程和父進程都從調用fork函數的下一條語句開始執行。這也是程序中會列印兩個結果的原因。 fork之後,操作系統會復制一個與父進程完全相同的子進程。不過這在操作系統看來,他們更像兄弟關系,這2個進程共享代碼空間,但是數據空間是互相獨立的,子進程數據空間中的內容是父進程的完整拷貝,指令指針也完全相同,但只有一點不同,如果fork成功,子進程中fork的返回值是0,父進程中fork的返回值是子進程的進程號,如果fork不成功,父進程會返回錯誤。2個進程一直同時運行,而且步調一致,在fork之後,他們分別作不同的工作,也就是分岔了。這也是fork為什麼叫fork的原因。至於哪一個先運行,與操作系統的調度演算法有關,而且這個問題在實際應用中並不重要,如果需要父子進程協同,可以通過原語的辦法實現同步來加以解決。 為了加深理解,看下面例子:#include <stdio.h>#include "../include/apue.h"#include <unistd.h>int main(){pid_t a_pid, b_pid;if((a_pid=fork())<0) // // 一定要有紅色括弧!! 沒有的話就a_pid永遠等於0,則永遠不會執行父進程!!!printf("error!");else if(a_pid==0){printf("the first child's pid=%d\n",getpid());printf("b\n");}else{printf("the parent's pid=%d\n",getpid());printf("a\n");} if((b_pid=fork())<0)printf("error!");else if(b_pid==0){printf("c\n");}else{printf("e\n");}return 0;} 輸出的結果: (1)the first child's pid=12623bcethe parent's pid=12622ace (2)the first child's pid=12638bthe parent's pid=12637acece (3)the first child's pid=12642bthe parent's pid=12641accee 很奇妙的結果。不過理解了「子進程和父進程都從調用fork函數的下一條語句開始執行」了也不奇怪了。同是這里引入理解fork的第三點 (3) fork函數不同於其他函數,在於它可能會有兩個或是多個返回值,而且是同時返回兩個值。繼續分析上面的例子。 理解上例的關鍵在於fork()的返回點在哪裡。Fork()同時返回兩個值。其中pid=0的這個返回值用來執行子進程的代碼,而大於0的一個返回值為父進程的代碼塊。第一次fork調用的時候生叉分為兩個進程,假設為a父進程和b子進程。他們分別各自在第二次fork調用之前列印了b和a各一次;在第一次叉分的這兩個進程中都含有 if((b_pid=fork())<0) // 一定要有紅色括弧!! 沒有的話就b_pid永遠等於0{printf("error!");}else if(b_pid==0)printf("c/n");elseprintf("e/n");這段代碼。很明顯,a父進程和b子進程在這段代碼中又各自獨立的被叉分為兩個進程。這兩個進程每個進程又都列印了e,c各一次。到此,在程序中總共列印兩次c,e和一次a,b。總共6個字母。註:在第一次叉分為兩個進程的時候父子進程含有完全相同的代碼(第二次仍然相同),只是因為在父子進程中返回的PID的值不同,父進程代碼中的PID的值大於0,子進程代碼中的值等於0,從而通過if這樣的分支選擇語句來執行各自的任務。 當然在使用fork中還有很多細節,比如輸出時,對緩沖區的不同處理會使父子進程執行過程中輸出不同,以及fork後,子進程的exec和exit的一些實現細節。以後再說。
2、fork系統調用的執行過程是怎樣
(代碼驗證) fork確實創建了一個子進程並完全復制父進程,但是子進程是從fork後面那個指令開始執行的。
對於原因也很合邏輯,如果子進程也從main開頭到尾執行所有指令,那它執行到fork指令時也必定會創建一個子子進程,如此下去這個小小的程序就可以創建無數多個進程可以把你的電腦搞癱瘓,所以fork作者肯定不會傻到這種程度fork和線程,進程的理解2011-10-11 10:09 本文分為三部分:1. 什麼是fork?2. fork用途?3. fork怎麼工作? 1. 什麼是fork?Fork源於OS中多線程任務的需要。在傳統的Unix環境下,有兩個基本的操作用於創建和修改進程:函數fork( )用來創建一個新的進程,該進程幾乎是當前進程的一個完全拷貝;函數族exec( )用來啟動另外的進程以取代當前運行的進程。下面說一下進程和線程。進程的簡單理解就是:一個進程表示的就是一個可執行程序的一次執行過程中的一個狀態。一個進程,主要包含三個元素:一個可以執行的程序; --- 代碼段
和該進程相關聯的全部數據(包括變數,內存空間,緩沖區等等); --- 數據段
程序的執行上下文(execution context)。 --- 堆棧段 "代碼段",顧名思義,就是存放了程序代碼的數據,假如機器中有數個進程運行相同的一個程序,那麼它們就可以使用相同的代碼段。"堆棧段"存放的就是子程序的返回地址、子程序的參數以及程序的局部變數。而數據段則存放程序的全局變數,常數以及動態數據分配的數據空間(比如用malloc之類的函數取得的空間)。 一般的CPU都有上述三種段寄存器,以方便操作系統的運行。這三個部分也是構成一個完整的執行序列的必要的部分。系統如果同時運行數個相同的程序,它們之間就不能使用同一個堆棧段和數據段。 操作系統對進程管理,最典型的是通過進程表完成的。進程表裡再通過一個稱為「程序計數器(program counter, pc)」的寄存器來完成「上下文的切換」。(實際的上下文交換需要涉及到更多的數據,和fork無關,不再多說,PC主要用於指出程序當前已經執行到哪裡,是進程上下文的重要內容,換出CPU的進程要保存這個寄存器的值,換入CPU的進程,也要根據進程表中保存的本進程執行上下文信息,更新這個寄存器)。 進程表中的每一個表項,記錄的是當前操作系統中一個進程的情況。對於單 CPU的情況而言,每一特定時刻只有一個進程佔用 CPU,但是系統中可能同時存在多個活動的(等待執行或繼續執行的)進程。
PC用於指出當前佔用 CPU的進程要執行的下一條指令的位置。 當分給某個進程的 CPU時間已經用完,操作系統將該進程相關的寄存器的值,保存到該進程在進程表中對應的表項裡面;把將要接替這個進程佔用 CPU的那個進程的上下文,從進程表中讀出,並更新相應的寄存器(這個過程稱為「上下文交換(process context switch)」 下面繼續說fork了。當程序執行到下面的語句:pid=fork(); 操作系統創建一個新的進程(子進程),並且在進程表中相應為它建立一個新的表項。新進程和原有進程的可執行程序是同一個程序;上下文和數據,絕大部分就是原進程(父進程)的拷貝,但它們是兩個相互獨立的進程!此時程序寄存器pc,在父、子進程的上下文中都聲稱,這個進程目前執行到fork調用即將返回(此時子進程不佔有CPU,子進程的pc不是真正保存在寄存器中,而是作為進程上下文保存在進程表中的對應表項內)。問題是怎麼返回。它們的返回順序是不確定的,取決於OS內的調度。如果想明確它們的執行順序,就得實現「同步」,或者是使用vfork()。這里假設父進程繼續執行,操作系統對fork的實現,使這個調用在父進程中返回剛剛創建的子進程的pid(一個正整數),所以下面的if語句中pid<0, pid==0的兩個分支都不會執行。所以一般執行fork後都會有兩個輸出。 2. Fork用途歸結起來有兩個:第一, 一個進程希望復制自身,從而父子進程能執行不同代碼段。第二, 進程想執行另外一個程序歸結起來說就是實現多線程。C語言多線程實現需要自己控制來實現,這個比JAVA要復雜。 3. Fork怎麼工作?先看一個例子:#include <unistd.h>;#include <sys/types.h>;int main (){ pid_t pid; pid=fork(); // 1)從這里開始程序分岔,父子進程都從這一句開始執行一次 if (pid < 0) printf("error!"); else if (pid == 0) printf("child process, process id is %dn", getpid()); else // pid > 0 printf("parent process, process id is %dn",getpid());
return 0;}結果:[root@localhost yezi]# ./a.out
parent process, process id is 4285 對於上面程序段有以下幾個關鍵點: (1)返回值的問題:正確返回:父進程中返回子進程的pid,因此> 0;子進程返回0
錯誤返回:-1 子進程是父進程的一個拷貝。即,子進程從父進程得到了數據段和堆棧段的拷貝,這些需要分配新的內存;而對於只讀的代碼段,通常使用共享內存的方式訪問。父進程與子進程的不同之處在於:fork的返回值不同——父進程中的返回值為子進程的進程號,而子進程為0。只有父進程執行的getpid()才是他自己的進程號。對子進程來說,fork返回給它0,但它的pid絕對不會是0;之所以fork返回0給它,是因為它隨時可以調用getpid()來獲取自己的pid; (2) fork返回後,子進程和父進程都從調用fork函數的下一條語句開始執行。這也是程序中會列印兩個結果的原因。 fork之後,操作系統會復制一個與父進程完全相同的子進程。不過這在操作系統看來,他們更像兄弟關系,這2個進程共享代碼空間,但是數據空間是互相獨立的,子進程數據空間中的內容是父進程的完整拷貝,指令指針也完全相同,但只有一點不同,如果fork成功,子進程中fork的返回值是0,父進程中fork的返回值是子進程的進程號,如果fork不成功,父進程會返回錯誤。2個進程一直同時運行,而且步調一致,在fork之後,他們分別作不同的工作,也就是分岔了。這也是fork為什麼叫fork的原因。至於哪一個先運行,與操作系統的調度演算法有關,而且這個問題在實際應用中並不重要,如果需要父子進程協同,可以通過原語的辦法實現同步來加以解決。 為了加深理解,看下面例子:#include <stdio.h>
#include "../include/apue.h"
#include <unistd.h>int main(){pid_t a_pid, b_pid;
if((a_pid=fork())<0) // // 一定要有紅色括弧!! 沒有的話就a_pid永遠等於0,則永遠不會執行父進程!!!
printf("error!");
else if(a_pid==0){printf("the first child's pid=%d\n",getpid());
printf("b\n");}else{printf("the parent's pid=%d\n",getpid());
printf("a\n");
} if((b_pid=fork())<0)
printf("error!");
else if(b_pid==0){printf("c\n");}else{printf("e\n");}return 0;} 輸出的結果: (1)the first child's pid=12623bcethe parent's pid=12622ace (2)the first child's pid=12638bthe parent's pid=12637acece (3)the first child's pid=12642bthe parent's pid=12641accee 很奇妙的結果。不過理解了「子進程和父進程都從調用fork函數的下一條語句開始執行」了也不奇怪了。同是這里引入理解fork的第三點 (3) fork函數不同於其他函數,在於它可能會有兩個或是多個返回值,而且是同時返回兩個值。繼續分析上面的例子。 理解上例的關鍵在於fork()的返回點在哪裡。Fork()同時返回兩個值。其中pid=0的這個返回值用來執行子進程的代碼,而大於0的一個返回值為父進程的代碼塊。第一次fork調用的時候生叉分為兩個進程,假設為a父進程和b子進程。他們分別各自在第二次fork調用之前列印了b和a各一次;在第一次叉分的這兩個進程中都含有 if((b_pid=fork())<0) // 一定要有紅色括弧!! 沒有的話就b_pid永遠等於0{printf("error!");}else if(b_pid==0)
printf("c/n");elseprintf("e/n");
這段代碼。很明顯,a父進程和b子進程在這段代碼中又各自獨立的被叉分為兩個進程。這兩個進程每個進程又都列印了e,c各一次。到此,在程序中總共列印兩次c,e和一次a,b。總共6個字母。
註:在第一次叉分為兩個進程的時候父子進程含有完全相同的代碼(第二次仍然相同),只是因為在父子進程中返回的PID的值不同,父進程代碼中的PID的值大於0,子進程代碼中的值等於0,從而通過if這樣的分支選擇語句來執行各自的任務。 當然在使用fork中還有很多細節,比如輸出時,對緩沖區的不同處理會使父子進程執行過程中輸出不同,以及fork後,子進程的exec和exit的一些實現細節。以後再說。
3、在LInux下怎麼樣進行父子進程同步
/*
* 使用信號實現父子進程之間的同步
*
* TELL_WAIT(): set things up for TELL_xxx & WAIT_xxx
* TELL_PARENT(): tell parent we are done
* WAIT_PARENT(): wait for parent
* TELL_CHILD(): tell child we are done
* WAIT_CHILD(): wait for child
*
* SIGUSR1: the signal parent sends to child
* SIGUSR2: the signal child sends to parent
*/
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
static volatile sig_atomic_t sigflag;
static sigset_t newmask, oldmask, zeromask;
/* signal handler for SIGUSR1 and SIGUSR2 */
static void sig_usr(int signo)
{
sigflag = 1;
return;
}
void TELL_WAIT()
{
if(signal(SIGUSR1, sig_usr) == SIG_ERR)
printf("signal SIGUSR1 error\n");
if(signal(SIGUSR2, sig_usr) == SIG_ERR)
printf("signal SIGUSR2 error\n");
sigemptyset(&zeromask);
sigemptyset(&newmask);
sigaddset(&newmask, SIGUSR1);
sigaddset(&newmask, SIGUSR2);
/* block SIGUSR1 and SIGUSR2, and save current signal mask */
if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
printf("SIG_BLOCK error\n");
}
void TELL_PARENT(pid_t pid)
{
kill(pid, SIGUSR2); /* tell parent we are done */
}
void WAIT_PARENT()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
sigflag = 0;
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void TELL_CHILD(pid_t pid)
{
kill(pid, SIGUSR1);
}
void WAIT_CHILD()
{
while(sigflag == 0)
sigsuspend(&zeromask); /* wait for parent */
sigflag = 0;
/* reset signal mask */
if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
printf("SIG_SETMASK error\n");
}
void do_task(char *task_str)
{
printf("%s\n", task_str);
}
/* parent goes first program */
int main()
{
pid_t pid;
TELL_WAIT();
pid = fork();
if(pid < 0) {
printf("fork error\n");
}
else if(pid == 0) {
WAIT_PARENT();
do_task("child task\n");
}
else {
do_task("parent task\n");
TELL_CHILD(pid);
}
return 0;
}
/* child goes first program*/
int main()
{
pid_t pid;
TELL_WAIT();
pid = fork();
if(pid < 0) {
printf("fork error\n");
}
else if(pid == 0) {
do_task("child task\n");
TELL_PARENT(getppid());
}
else {
WAIT_CHILD();
do_task("parent task\n");
}
return 0;
}
/*
* 使用管道實現父子進程同步
*
* 父進程在調用TELL_CHILD 時經由上一個管道寫一個字元p,子進程在
* 調用TELL_PARENT時,經由下一個管道寫一個字元c。相應的WAIT_XXX
* 函數調用read讀一個字元,沒有讀到字元時阻塞(睡眠等待)。
*
*/
static int pfd1[2], pfd[2];
void TELL_WAIT()
{
if(pipe(pfd1) < 0 || pipe(pfd2) < 0)
printf("pipe error\n");
}
void TELL_PARENT(pid_t pid)
{
if(write(pfd2[1], "c", 1) != 1)
printf("write error\n");
}
void WAIT_PARENT()
{
char c;
if(read(pfd1[0], &c, 1) != 1)
printf("read error\n");
if(c != 'p')
printf("WAIT_PARENT: incorrect data\n");
}
void TELL_CHILD(pid_t pid)
{
if(write(pfd1[1], "p", 1) != 1)
printf("write error\n");
}
void WAIT_CHILD()
{
char c;
if(read(pfd1[0], &c, 1) != 1)
printf("read error\n");
if(c != 'c')
printf("WAIT_CHILD: incorrect data\n");
}
4、node js fork 多進程 怎麼判斷
nodejs是一種單線程模型,但是,使用nodejs的child_process模塊可以實現多進程任務。利用child_process可以創建子進程,實現子進程和主進程之間的通信。
nodejs v0.12.7版本child_process提供以下同步和非同步的方式創建進程:
非同步創建:
child_process.spawn(command[, args][, options])
options.stdio
options.detached
options.customFds
child_process.exec(command[, options], callback)
child_process.execFile(file[, args][, options][callback])
child_process.fork(molePath[, args][, options])
同步創建:
child_process.spawnSync(command[, args][, options])
child_process.execFileSync(command[, args][, options])
child_process.execSync(command[, options])
。。。。。
5、git fork後如何保持同步
需要藉助在windows下安裝github出現的一個工具Git Shell,以前一直不知道它的用處,這次體會一下。
1)進入本地項目目錄,輸入 git remote -v:
籃框內的url是我Github上的項目,紅框內的url是原作者項目。如果沒有upstream,即沒有原作者項目的url,你需要自己添加:$ git remote add upstream <原作者項目的URL>
2)將原作者項目更新的內容同步到我的本地項目(不是我Github網上的項目):
a) Fetch the branches and their respective commits from the upstream repository. Commits to master will be stored in a local branch, upstream/master .
b) Check out your fork's local master branch.
c) 接下來就是合並這兩個分支,將原作者項目的修改同步到自己這里(注意還是指本地項目,不是自己Github空間里的項目)。Merge the changes fromupstream/master into your local master branch. This brings your fork's master branch into sync with the upstream repository, without losing your local changes.
至此我的本地項目已經於原作者項目同步了。
3)也讓自己Github空間里的項目得到同步:
通過另一個工具Github.exe,將本地項目的修改(即與原作者項目同步的內容)push到自己的Github上
6、之前如何設置讓子進程不繼承父進程的信號處理函數
編寫一段程序,使用系統調用fork( )創建兩個子進程。當此程序運行時,在系統中有一個父進程和兩個子進程活動。讓每一個進程在屏幕上顯示一個字元;父進程顯示字元「a」,子進程分別顯示字元「b」和「c」。試觀察記錄屏幕上的顯示結果,並分析原因。〈程序〉 #include main() { int p1,p2; if(p1=fork()) /*子進程創建成功*/ putchar('b'); else { if(p2=fork()) /*子進程創建成功*/ putchar('c'); else putchar('a'); /*父進程執行*/ } } bca(有時會出現abc的任意的排列) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 編制一段程序,實現進程的管道通信。使用系統調用pipe()建立一條管道線。兩個子進程p1和p2分別向通道個寫一句話: child1 process is sending message! child2 process is sending message! 而父進程則從管道中讀出來自兩個進程的信息,顯示在屏幕上。 〈程序〉 #include #include #include int pid1,pid2; main( ) { int fd[2]; char outpipe[100],inpipe[100]; pipe(fd); /*創建一個管道*/ while ((pid1=fork( ))==-1); if(pid1==0) { lockf(fd[1],1,0); sprintf(outpipe,"child 1 process is sending message!"); /*把串放入數組outpipe中*/ write(fd[1],outpipe,50); /*向管道寫長為50位元組的串*/ sleep(5); /*自我阻塞5秒*/ lockf(fd[1],0,0); exit(0); } else { while((pid2=fork( ))==-1); if(pid2==0) { lockf(fd[1],1,0); /*互斥*/ sprintf(outpipe,"child 2 process is sending message!"); write(fd[1],outpipe,50); sleep(5); lockf(fd[1],0,0); exit(0); } else { wait(0); /*同步*/ read(fd[0],inpipe,50); /*從管道中讀長為50位元組的串*/ printf("%s\n",inpipe); wait(0); read(fd[0],inpipe,50); printf("%s\n",inpipe); exit(0); } } } 〈運行結果〉延遲5秒後顯示: child1 process is sending message! 再延遲5秒: child2 process is sending message! 附:我承認我是復制的 不過很符合題意~
7、Git 怎樣保證fork出來的project和原project同步更新
1. 在 Fork 的代碼庫中添加上游代碼庫的 remote 源,該操作只需操作一次即可。
如: 其中# upstream 表示上游代碼庫名, 可以任意。
git remote add upstream https://github.scm.corp.ebay.com/montage/frontend-ui-workspace
2. 將本地的修改提交 commit
3. 在每次 Pull Request 前做如下操作,即可實現和上游版本庫的同步。
3.1 : git remote update upstream
3.2 : git rebase upstream/{branch name}
需要注意的是在操作3.2之前,一定要將checkout到{branch name}所指定的branch,
如: git checkout develop
4. Push 代碼到 Github
git push
8、請問如何在fork()後讓子進程先等待父進程退出?
我感覺你似乎可以用getppid獲取父進程pid,
然後waitpid,
我猜的,
你不妨試試,
不行的話不要怪我,
哈哈如果waitpid不能wait父進程的話,
或許你應該使用某種同步鎖,
比如mutex自己實現這種同步.