fork并发进程处理

线程并发

处理僵尸线程

很多时候我们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;
}


转载于:https://my.oschina.net/u/215677/blog/631872

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值