线程并发
处理僵尸线程
很多时候我们fork创建的子进程终止时,需要服务器进程进行清理,倘若未进行处理将会处理大量的僵尸线程,那么我们可以选择将进忽略,并交给init进程进行处理。
signal(SIGCHLD, SIG_IGN);
//在fork创建的处理模块当中添加下列的代码,当子线程处理结束后将其退出,并由Init来释放资源。
exit(EXIT_SUCCESS);
fork 创建进程
fork是创建一个当前运行进程的副本,只能通过返回值去区分当前是父线程还是子线程。fork是一次调用两次返回,通常返回下面两类.
- 当fork()返回的是>0的时候表示当前的是父进程
- 当fork()返回的为0表示当前是子进程.
- 返回<0表示当前创建的进程出现错误 ###示例一
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main( void ) {
int pid = fork();
if ( pid == 0 ) {
printf( "当前处于子线程运行" );
} else {
printf("当处于父进程运行,当前所创建的子线程的ID: %d\n",pid);
}
return 0;
}
运行的结果
gcc ForkTest.c ./a.out 当处于父进程运行,当前所创建的子线程的ID: 6761 当前处于子线程运行%
###getpid() 通过调用getpid可以获得自己的标识. 示例2
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main( void ) {
int pid = fork();
if ( pid == 0 ) {
printf( "当前处于子线程运行,id:%d",(int)getpid() );
} else {
printf("当处于父进程运行,父进程的ID:%d,当前所创建的子线程的ID: %d\n",(int)getpid(),pid);
}
return 0;
}
运行结果
gcc ForkTest2.c ./a.out 当处于父进程运行,父进程的ID:6837,当前所创建的子线程的ID: 6838 当前处于子线程运行,id:6838%
示例3
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main( void ) {
int sum=50;
int pid;
for (int i = 0; i < 2; i++) {
pid=fork();
if(pid==0){
printf("创建了一个子线程成功\n");
printf("pid=%d,ppid=%d\n",getpid(),getppid());
printf("i=%d\n",i);
}
else if(pid>0){
printf("父进程\n");
printf("pid=%d,ppid=%d\n",getpid(),getppid());
printf("i=%d\n",i);
}
}
return 0;
}
运行结果
gcc ForkTest.c /a.out 父进程 pid=7226,ppid=2513 i=0 父进程 pid=7226,ppid=2513 i=1 创建了一个子线程成功 pid=7227,ppid=7226 i=0 创建了一个子线程成功 pid=7228,ppid=7226 i=1 父进程 pid=7227,ppid=1 i=1 创建了一个子线程成功 pid=7229,ppid=7227 i=1 
上面的程序我们进行一个for循环,本意是想通过这个循环调用fork创建两个子进程,可是执行的结果却是创建了三个进程 产生这个问题的原因是: 创建了7227这个副本的时候我们也拷贝了父进程的所有的代码,那么7227也会进入for循环,这里i=1就会在子线程也会调用一次fork这样就创建了三个线程
示例四 解决上面所述的问题
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main( void ) {
int sum=50;
int pid;
for (int i = 0; i < 2; i++) {
pid=fork();
if(pid==0){
printf("创建了一个子线程成功\n");
printf("pid=%d,ppid=%d\n",getpid(),getppid());
printf("i=%d\n",i);
break;
}
else if(pid>0){
printf("父进程\n");
printf("pid=%d,ppid=%d\n",getpid(),getppid());
printf("i=%d\n",i);
}
}
return 0;
}
gcc ForkTest.c ./a.out 父进程 pid=7326,ppid=2513 i=0 父进程 pid=7326,ppid=2513 i=1 创建了一个子线程成功 pid=7327,ppid=7326 i=0 创建了一个子线程成功 pid=7328,ppid=7326 i=1
网上面试题讲解
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
int i;
for(i=0; i<2; i++){
I fork();
printf("%d,%d\n",getpid(),getppid());
}
wait(NULL);
wait(NULL);
return 0;
}