今天,師兄問(wèn)我一個(gè)問(wèn)題說(shuō):小濤啊,創(chuàng)建兩個(gè)進(jìn)程太簡(jiǎn)單了,怎么創(chuàng)建多個(gè)進(jìn)程呢?我說(shuō)那還不容易,看下邊代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | int main()
{
pid_t pid[2];
int i;
printf("This is %d\n",getpid());
for(i = 0;i < 2;i++ ){
if((pid[0] = fork()) < 0){
printf("Fork() Error!");
exit(-1);
}
if(pid[0] == 0)
printf("This is parent %d,child is %d\n",getppid(),getpid());
else
wait(5);
}
return 0;
}
|
好,這段代碼還是挺簡(jiǎn)單的,我們的意思是:主線程通過(guò)循環(huán)創(chuàng)建2個(gè)子進(jìn)程,這時(shí)系統(tǒng)中的總進(jìn)程數(shù)應(yīng)該是3,看看輸出結(jié)果吧:
這個(gè)結(jié)果圖看的效果不好,我們看個(gè)直接點(diǎn)的:
這下你明白了吧,問(wèn)題沒(méi)有想象中的那樣簡(jiǎn)單,父進(jìn)程現(xiàn)在標(biāo)號(hào)為1的循環(huán)中創(chuàng)了一個(gè)子進(jìn)程,然后第二次循環(huán),前邊的兩個(gè)線程個(gè)創(chuàng)建一個(gè)子進(jìn)程,這時(shí)明顯系統(tǒng)中有四個(gè)進(jìn)程,還是不懂?在下邊的時(shí)序圖吧:
這下你應(yīng)該明白了吧,好了問(wèn)題知道了,怎么解決,方法有二;
方法一:直接看代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | void createsubprocess(int num)
{
pid_t pid;
int i;
for(i=0;i<num;i++)
{
pid=fork();
if(pid==0||pid==-1)
{
break;
}
}
if(pid==-1)
{
perror("fail to fork!\n");
exit(1);
}
else if(pid==0)
{
printf("子進(jìn)程id=%d,其對(duì)應(yīng)的父進(jìn)程id=%d\n",getpid(),getppid());
exit(0);
}
else
{
printf("父進(jìn)程id=%d\n",getpid());
exit(0);
}
}
|
這種方法的關(guān)鍵就在于每次循環(huán)時(shí),如果發(fā)現(xiàn)是子進(jìn)程就直接從創(chuàng)建子進(jìn)程的循環(huán)中跳出來(lái),不讓你進(jìn)入循環(huán),這樣就保證了每次只有父進(jìn)程來(lái)做循環(huán)創(chuàng)建子進(jìn)程的工作。
方法二:直接看代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | void createsubprocess(int num,int max)
{
if(num>=max)return;
pid=fork();
if(pid<0)
{
perror("fork error!\n");
exit(1);
}
else if(pid==0)
{
sleep(3);
printf("子進(jìn)程id=%d,父進(jìn)程id=%d\n",getpid(),getppid());
}
else
{
num++;
if(num==1)printf("父進(jìn)程id=%d\n",getpid());
if(num<max)createsubprocess(num,max);
sleep(5);
}
}
|
這里的關(guān)鍵在于遞歸操作,只有父進(jìn)程才進(jìn)入遞歸創(chuàng)建子進(jìn)程,子進(jìn)程不進(jìn)行這樣的操作。