linux创建2个进程每个进程有2个线程,【Linux】利⽤fork()
创建多个线程
在《【Linux】fork()》(点击打开链接)只是简单交代了如同利⽤fork()创建⼦线程的⽅法,实际是更应该说将⼀个程序⼀分为⼆的⽅法。还有很多事情隐藏在其中值得细致思考。由于fork()结构的特殊性,如果要⽤fork()创建多个线程,并不像pthread_create()那样轻松,⽽且最关键的⼀点,是你利⽤for循环和fork()创建出来的多线程,会不明不⽩地多出N条线程。这主要是由于对fork()的理解不够所造成的。⽐如如下代码:
#include
int main(){
pid_t pid[2];
int i;
for(i=0;i<2;i++){
一个线程可以包含多个进程if((pid[i]=fork())<0){
printf("Fork() Error!");
}
else if(pid[i]==0){
printf("This is parent %d,child is %d\n",getppid(),getpid());
}
else{
wait(5);
}
}
return 0;
}
看起来好像没有任何问题,创建2条⼦线程,就是在原有fork()的基础上,建⽴⼀个for⽽已。
但就是不知道会创建出4条线程。那是因为,问题没有想象中的那样简单,⽗进程现在标号为i=1的循环中创了⼀个⼦进程,然后第⼆次循环,前边的第⼀个⼦线程⼜创建⼀个⼦进程,这时明显系统中有四个进程。如下图所⽰:
因此这种创建多个⼦进程的⽅式不可取,是否⼀定需要⽤pthread_create呢?其实并不是,可以⽤如下的结构,创建多个⼦进程,以要创建4个为例:
#include
#define MAX_THREAD 4//设置⼦线程数量
int main(){
int i,status,pid;
for(i=0;i
status=fork();
if (status==0||status ==-1){
break;
/*每次循环时,
如果发现是⼦进程就直接从创建⼦进程的循环中跳出来,
不让你进⼊循环,
这样就保证了每次只有⽗进程来做循环创建⼦进程的⼯作
*/
}
}
if(status==-1){//⼀般不会这种情况!
printf("创建的⼦进程,失败");
}
else if(status==0){//每个⼦进程都会执⾏的代码
printf("⼦线程id=%d,我⽼爸的id=%d,i=%d\n",getpid(),getppid(),i);
wait(status,NULL,0);
}
else{
printf("⽗进程id=%d\n",getpid());
while((pid=wait(&status))>0){
printf("终结id为%d的⼦线程\n", pid);
}
}
return 0;
}
⼤家需要⾃⼰的⼦进程做什么,直接在else if(status==0){}这个结构⾥⾯改就⾏了。
同时,注意到这⾥停⽌⼦进程与《【Linux】fork()》(点击打开链接)停⽌单个⼦进程是不通。⽗进程⼀般不做任何事情,相当于
pthread_create⾥⾯的主函数,具体见《【Linux】线程》(点击打开链接),他唯⼀的职责就是让等待每⼀个⼦线程停⽌。
运⾏结果如下图:
⼤家注意到这个运⾏结果很有意思,i是从3到0倒着来输出的。本⾝程序就很有意思,if-else if-else这个结构就游离在for循环之外,却如同将这段代码做了4次。
这是因为fork()保存现场,将线程压⼊栈的特性。i=0时候这个现场被创建的⼦线程最先⼊栈,所以他是最后输出的。
if-else if-else这个结构相当于将线程栈⾥⾯的线程经过else if中的处理之后⼀⼀出栈。
else if中最初能操作的东西,是⼦线程⼊栈时候的状态。
⼤家明⽩了吗,其实这跟汇编语⾔⾥⾯的循环其实很类似的。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论