当前位置: 首页> 游戏> 手游 > 免费主题大全软件下载_24小时b站十大直播间_站长seo推广_广州新闻头条最新消息

免费主题大全软件下载_24小时b站十大直播间_站长seo推广_广州新闻头条最新消息

时间:2025/7/14 17:57:00来源:https://blog.csdn.net/2301_76197086/article/details/143302221 浏览次数:0次
免费主题大全软件下载_24小时b站十大直播间_站长seo推广_广州新闻头条最新消息

目录

一、子进程会给父进程发送SIGCHLD信号

二、父进程无需手动在main函数中等待子进程

三、问题1:多个子进程同时结束

四、问题2: 某个子进程永不退出

五、不等待子进程退出


一、子进程会给父进程发送SIGCHLD信号

子进程退出时并非悄无声息,而是会给父进程发送退出信号,即SIGCHLD。但是父进程对于该信号并不会作出处理,因为SIGCHLD信号的默认处理方式是Ign,即忽略。

父进程可以对SIGCHLD信号进行自定义捕捉,验证父进程收到了该信号:

#include <iostream>
#include <signal.h>
using namespace std;
void handler(int signum)
{cout<<"get a sig: "<<signum<<endl;
}
int main()
{signal(SIGCHLD,handler);//父进程对SIGCHLD信号自定义捕捉pid_t id=fork();//创建子进程if(id==0)//子进程{cout<<"I am child process, pid is: "<<getpid()<<endl;sleep(3);exit(1);}//父进程sleep(100);
}

二、父进程无需手动在main函数中等待子进程

根据上述特点,父进程就无需手动在main函数中使用waitpid函数进行非阻塞等待,而是在自定义函数中进行等待,父进程可以做其他任务。因为如果父进程调用了自定义函数,说明收到了SIGCHLD信号,此时子进程已经结束。

#include <iostream>
#include <signal.h>
#include <sys/wait.h>
using namespace std;
void DoOtherThing()
{cout<<"do other things"<<endl;
}
void handler(int signum)
{cout<<"get a sig: "<<signum<<endl;pid_t rid=waitpid(-1,nullptr,0);//第一个参数传-1可以等待任何进程if(rid>0){cout<<"wait child success, rid is: "<<rid<<endl;}
}
int main()
{signal(SIGCHLD,handler);//父进程对SIGCHLD信号自定义捕捉pid_t id=fork();//创建子进程if(id==0)//子进程{cout<<"I am child process, pid is: "<<getpid()<<endl;sleep(3);exit(1);}//父进程while(true){DoOtherThing();sleep(1);}
}

三、问题1:多个子进程同时结束

如果有多个子进程同时退出,同时向父进程发送SIGCHLD信号,但是父进程一次只能处理一个SIGCHLD信号,会将其他的SIGCHLD屏蔽,这样就会导致无法获取所有子进程的退出信息。

因此需要优化handler自定义函数:将进程等待设置为循环,直到所有子进程结束等待失败,结束循环(当所有子进程都结束时,即没有子进程时waitpid函数会等待失败)

#include <iostream>
#include <signal.h>
#include <sys/wait.h>
using namespace std;
void DoOtherThing()
{cout << "do other things" << endl;
}
void handler(int signum)
{//cout << "get a sig: " << signum << endl;while (true){pid_t rid = waitpid(-1, nullptr, 0); // 第一个参数传-1可以等待任何进程if (rid > 0){cout << "get a sig: " << signum << ", wait child success, rid is: " << rid << endl;}else // 等待失败,说明没有子进程可以等待了,子进程全部等待成功了{break;}}
}
int main()
{signal(SIGCHLD, handler); // 父进程对SIGCHLD信号自定义捕捉for (int i = 0; i < 5; ++i)//创建5个子进程{pid_t id = fork(); // 创建子进程if (id == 0)       // 子进程{cout << "I am child process, pid is: " << getpid() << endl;sleep(1);exit(1);}}// 父进程while (true){DoOtherThing();sleep(1);}
}

四、问题2: 某个子进程永不退出

假设存在多个子进程,其中某个进程永远不会退出,那么程序将永远死循环在handler函数中,main函数就永远不会结束。

因此需要进一步优化handler函数:将waitpid函数改为非阻塞等待,传入WNOHANG选项

#include <iostream>
#include <signal.h>
#include <sys/wait.h>
using namespace std;
void DoOtherThing()
{cout << "do other things" << endl;
}
void handler(int signum)
{//cout << "get a sig: " << signum << endl;while (true){pid_t rid = waitpid(-1, nullptr, WNOHANG); // 第一个参数传-1可以等待任何进程if (rid > 0){cout << "get a sig: " << signum << ", wait child success, rid is: " << rid << endl;}else if(rid < 0)// 等待失败,说明没有子进程可以等待了,子进程全部等待成功了{cout<<"wait child sucess done"<<endl;break;}else//没有收到SIGCHLD信号,但是还有子进程没退出{cout<<"wait child sucess done"<<endl;break;}}
}
int main()
{signal(SIGCHLD, handler); // 父进程对SIGCHLD信号自定义捕捉for (int i = 0; i < 5; ++i)//创建5个子进程{pid_t id = fork(); // 创建子进程if (id == 0)       // 子进程{cout << "I am child process, pid is: " << getpid() << endl;sleep(1);exit(1);}}// 父进程while (true){DoOtherThing();sleep(1);}
}

五、不等待子进程退出

父进程等待子进程退出主要有两个目的:1.避免子进程成为僵尸进程,释放子进程资源;2.获取子进程退出信息

如果不想等待子进程退出,可以让父进程调用signal函数,将SIGCHLD信号的默认处理方式设置为SIG_IGN,这样fork出来的子进程在结束时会被自动清理掉,不会产生僵尸进程,也不会给父进程发送任何信号或者退出信息

(注意:SIG_CHLD信号的默认处理方式本身就是Ign,但是该忽略动作是系统用的,和我们手动指定的SIG_IGN不同,只有是SIG_IGN才会使子进程退出时直接释放资源,不给父进程发送任何信息)

#include <iostream>
#include <signal.h>
#include <sys/wait.h>
using namespace std;
void DoOtherThing()
{cout << "do other things" << endl;
}
int main()
{signal(SIGCHLD, SIG_IGN); // 忽略SIGCHLD信号for (int i = 0; i < 5; ++i)//创建5个子进程{pid_t id = fork(); // 创建子进程if (id == 0)       // 子进程{cout << "I am child process, pid is: " << getpid() << endl;sleep(1);exit(1);}}// 父进程while (true){DoOtherThing();sleep(1);}
}

关键字:免费主题大全软件下载_24小时b站十大直播间_站长seo推广_广州新闻头条最新消息

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: