coding---进程、线程的回收

本文介绍了如何处理子进程和子线程结束后遗留的资源回收问题,包括使用wait和waitpid函数回收子进程PID资源,以及通过pthread_join和pthread_detach方法回收子线程资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

子进程PID回收

子进程先于父进程结束,则父进程需要调用wait()waitpid()来回收子进程的pid资源,否则子进程会变为僵尸进程,直到父进程退出后,有init回收僵尸进程。回收子进程pid的方法:

1)  使用信号量

每个子进程退出时都会发送SIGCHLD信号量,父进程只要该信息量处理函数中调用wait()waitpid(-1,null,0)函数回收即可。

优点:立即触发,不需要父进程主流程支持什么。

缺点:不能区分子进程pid,只要有SIGCHLD就会触发,waitwaitpid返回即为子进程pid

2)  循环检测子进程

父进程循环执行waitpid(),检测子进程是否退出(比较傻,父进程什么也干不了,一直等着子进程退出)。

存在多个子进程时,需要循环多次;多个子进程同时退出时,SIGCHLD信号量会覆盖。

比较好的方法,父进程与子进程通过pipe句柄通信,父进程select/poll该句柄,及时得到子进程退出。(该方法没试过)

3)  由init回收子进程资源

父进程设置signal(SIGCHLD, SIG_IGN),屏蔽子进程退出信号;执行两次fork(),儿子进程直接退出,则孙子进程的父进程为init进程。

缺点:子进程、孙进程何时结束,父进程无法得知。

Wait()函数:阻塞直到任一子进程结束,有子进程退出,返回值为子进程pid;不存在子进程则出错,返回-1

Waitpid()函数:可以传递参数,比如“waitpid(pid, &Status, WNOHANG)”,pid指定子进程pidStatus保存子进程退出返回信息(正常退出、异常退出、进程返回值),WNOHANG表示函数立即返回,不会阻塞;指定pid不存在,返回-1;指定进程没结束,则返回0;进程结束则返回进程pid

 子线程资源回收

子线程退出后同样存在资源回收问题,子线程创建后默认是joinable状态,子线程退出后,显示创建的资源必须显示释放(如内存、句柄等),同一进程的其他线程必须使用pthread_join()回收子线程的资源,包括线程控制块、线程堆栈。pthread_join()函数是阻塞的,必然导致调用者挂起。如果不关心该线程退出时间,又需要安全的释放资源就必须将线程置为detach状态:

方法1:在创建线程前设置线程属性pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED),再使用该属性创建线程。

pthread_t   dwThreadId;
 pthread_attr_t      thread_attr;
 
 pthread_attr_init(&thread_attr);
 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); //设置线程为detached状态
 pthread_attr_setscope(&thread_attr, PTHREAD_SCOPE_SYSTEM); //设置线程调度范围为系统级
 if (stack > 0)
  pthread_attr_setstacksize(&thread_attr, stack);
 if (0 != pthread_create(&dwThreadId, &thread_attr,   (void *(*)(void *))startaddr, (LPVOID)parg)) {  //应用属性到具体线程
  hthread  = 0;
 } else {
  *dwThread = dwThreadId;
  hthread  = 1;
 }
 pthread_attr_destroy(&thread_attr);

方法2:线程启动时,主动调用pthread_detach(id) ,修改线程本身为detached状态。

线程退出包括多种场景,最好主动退出pthread_exit()如果是其他线程要求该线程退出,可以发送pthread_cancel(­)停止指定线程,这种方法比较危险,cancel信号会使子线程的很多系统调用报错退出,因此要求被cancel的线程设置安全退出点,即在没有复杂系统调用时执行pthread_testcancel()循环检测cancel信号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值