当前位置: 首页 > news >正文

现在做网站还有出路吗四川酒店网站建设

现在做网站还有出路吗,四川酒店网站建设,php 开发手机网站建设,原创服装设计师1. 理解子进程终止的机制 在Unix/Linux系统中,当子进程终止时,会向父进程发送一个SIGCHLD信号。父进程需要捕捉这个信号,并通过调用wait()或waitpid()等函数来回收子进程的资源。这一过程被称为“回收僵尸进程”。 如果父进程没有及时调用w…

1. 理解子进程终止的机制

在Unix/Linux系统中,当子进程终止时,会向父进程发送一个SIGCHLD信号。父进程需要捕捉这个信号,并通过调用wait()waitpid()等函数来回收子进程的资源。这一过程被称为“回收僵尸进程”。

如果父进程没有及时调用wait()或相关函数,子进程将会成为僵尸进程,占用系统资源,直到父进程终止或调用相应的等待函数。

2. 使用wait()waitpid()函数

  • wait():使父进程阻塞,直到任一子进程终止。它会返回终止子进程的PID,并存储子进程的退出状态。
  • waitpid():提供更精细的控制,可以等待特定的子进程或采用非阻塞方式。
例子:阻塞等待子进程终止
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>int main() {pid_t pid = fork();  // 创建子进程if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;}else if (pid == 0) {// 子进程执行的代码std::cout << "子进程PID:" << getpid() << " 启动。" << std::endl;sleep(2);  // 模拟子进程工作std::cout << "子进程PID:" << getpid() << " 结束。" << std::endl;return 42;  // 子进程以状态42退出}else {// 父进程执行的代码std::cout << "父进程PID:" << getpid() << " 等待子进程结束。" << std::endl;int status;pid_t terminated_pid = wait(&status);  // 阻塞等待任一子进程结束if (terminated_pid > 0) {if (WIFEXITED(status)) {std::cout << "子进程PID:" << terminated_pid << " 以状态 " << WEXITSTATUS(status) << " 退出。" << std::endl;}else if (WIFSIGNALED(status)) {std::cout << "子进程PID:" << terminated_pid << " 被信号 " << WTERMSIG(status) << " 终止。" << std::endl;}}else {std::cerr << "等待子进程失败。" << std::endl;}}return 0;
}

输出示例:

父进程PID:12345 等待子进程结束。
子进程PID:12346 启动。
子进程PID:12346 结束。
子进程PID:12346 以状态 42 退出。

代码解释:

  1. 父进程调用fork()创建子进程。
  2. 子进程执行自己的任务后,以状态42退出。
  3. 父进程调用wait()阻塞等待子进程结束,并获取子进程的退出状态。
  4. 父进程通过宏WIFEXITEDWEXITSTATUS判断子进程是否正常退出及其退出状态。

3. 使用SIGCHLD信号处理异步回收

为了避免父进程被阻塞,可以通过信号处理函数异步处理子进程的终止。这在需要父进程继续执行其他任务时非常有用。

例子:使用SIGCHLD处理子进程终止
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <cstring>// 信号处理函数
void sigchld_handler(int signum) {// 循环回收所有已终止的子进程while (true) {int status;pid_t pid = waitpid(-1, &status, WNOHANG);if (pid <= 0) {break;}if (WIFEXITED(status)) {std::cout << "[Signal Handler] 子进程PID:" << pid << " 以状态 " << WEXITSTATUS(status) << " 退出。" << std::endl;}else if (WIFSIGNALED(status)) {std::cout << "[Signal Handler] 子进程PID:" << pid << " 被信号 " << WTERMSIG(status) << " 终止。" << std::endl;}}
}int main() {// 注册SIGCHLD信号处理函数struct sigaction sa;sa.sa_handler = sigchld_handler;sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;if (sigaction(SIGCHLD, &sa, NULL) == -1) {std::cerr << "无法注册SIGCHLD处理器:" << strerror(errno) << std::endl;return 1;}pid_t pid = fork();  // 创建子进程if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;}else if (pid == 0) {// 子进程执行的代码std::cout << "子进程PID:" << getpid() << " 启动。" << std::endl;sleep(2);  // 模拟子进程工作std::cout << "子进程PID:" << getpid() << " 结束。" << std::endl;return 24;  // 子进程以状态24退出}else {// 父进程执行的其他任务std::cout << "父进程PID:" << getpid() << " 正在执行其他任务。" << std::endl;// 模拟父进程执行其他任务for (int i = 0; i < 5; ++i) {std::cout << "父进程执行中:" << i + 1 << std::endl;sleep(1);}// 父进程结束前确保所有子进程已被回收// 可以调用wait(NULL)或者让信号处理器完成回收}return 0;
}

输出示例:

父进程PID:12345 正在执行其他任务。
子进程PID:12346 启动。
父进程执行中:1
父进程执行中:2
子进程PID:12346 结束。
[Signal Handler] 子进程PID:12346 以状态 24 退出。
父进程执行中:3
父进程执行中:4
父进程执行中:5

代码解释:

  1. 注册SIGCHLD信号处理器
    • 使用sigaction结构体注册sigchld_handler函数作为SIGCHLD信号的处理器。
    • SA_RESTART标志用于在信号处理后自动重启被中断的系统调用。
    • SA_NOCLDSTOP标志表示当子进程停止或继续时,父进程不接收SIGCHLD信号。
  2. 创建子进程
    • 子进程执行自己的任务并以状态24退出。
  3. 父进程执行其他任务
    • 父进程在等待子进程结束的同时,继续执行其他任务,不会被阻塞。
  4. 信号处理函数sigchld_handler
    • 当子进程终止时,SIGCHLD信号会被触发,sigchld_handler函数会被调用。
    • 在函数内部,使用waitpidWNOHANG选项非阻塞地回收所有已终止的子进程,防止僵尸进程的产生。

4. 避免僵尸进程的策略

  • 及时调用wait()waitpid():确保父进程在子进程终止后,立即回收其资源。
  • 使用信号处理器:如上文所示,通过注册SIGCHLD信号处理器,可以在子进程终止时自动回收资源,而不需要父进程主动等待。
  • 设置SIGCHLDSIG_IGN:在一些系统上,可以通过将SIGCHLD信号的处理方式设置为忽略,从而自动回收子进程资源。这种方法不适用于所有情况,需谨慎使用。
例子:设置SIGCHLD为忽略
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <cstring>int main() {// 设置SIGCHLD为忽略signal(SIGCHLD, SIG_IGN);pid_t pid = fork();  // 创建子进程if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;}else if (pid == 0) {// 子进程执行的代码std::cout << "子进程PID:" << getpid() << " 启动。" << std::endl;sleep(2);  // 模拟子进程工作std::cout << "子进程PID:" << getpid() << " 结束。" << std::endl;return 0;}else {// 父进程执行其他任务std::cout << "父进程PID:" << getpid() << " 正在执行其他任务。" << std::endl;sleep(5);  // 父进程等待子进程结束}return 0;
}

注意事项:

  • 这种方法依赖于系统对SIGCHLD的具体实现,不保证在所有Unix/Linux系统中都有效。
  • 尽管简便,但可能无法获取子进程的退出状态,限制了错误处理和日志记录的能力。

5. 处理多个子进程的终止

当父进程创建多个子进程时,需要确保所有子进程的终止都被正确处理,以避免僵尸进程。可以在SIGCHLD处理函数中使用循环调用waitpid,直到所有终止的子进程都被回收。

例子:处理多个子进程
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <vector>
#include <cstring>// 信号处理函数
void sigchld_handler(int signum) {// 循环回收所有已终止的子进程while (true) {int status;pid_t pid = waitpid(-1, &status, WNOHANG);if (pid <= 0) {break;}if (WIFEXITED(status)) {std::cout << "[Signal Handler] 子进程PID:" << pid << " 以状态 " << WEXITSTATUS(status) << " 退出。" << std::endl;}else if (WIFSIGNALED(status)) {std::cout << "[Signal Handler] 子进程PID:" << pid << " 被信号 " << WTERMSIG(status) << " 终止。" << std::endl;}}
}int main() {// 注册SIGCHLD信号处理函数struct sigaction sa;sa.sa_handler = sigchld_handler;sigemptyset(&sa.sa_mask);sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;if (sigaction(SIGCHLD, &sa, NULL) == -1) {std::cerr << "无法注册SIGCHLD处理器:" << strerror(errno) << std::endl;return 1;}std::vector<pid_t> child_pids;// 创建多个子进程for (int i = 0; i < 3; ++i) {pid_t pid = fork();if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;}else if (pid == 0) {// 子进程执行的代码std::cout << "子进程PID:" << getpid() << " 启动。" << std::endl;sleep(2 + i);  // 模拟不同的工作时间std::cout << "子进程PID:" << getpid() << " 结束。" << std::endl;return i;}else {// 父进程记录子进程PIDchild_pids.push_back(pid);}}// 父进程执行其他任务std::cout << "父进程PID:" << getpid() << " 正在执行其他任务。" << std::endl;sleep(6);  // 等待所有子进程结束// 由于SIGCHLD处理器已经回收了子进程,父进程无需再次调用waitreturn 0;
}

输出:

父进程PID:12345 正在执行其他任务。
子进程PID:12346 启动。
子进程PID:12347 启动。
子进程PID:12348 启动。
子进程PID:12346 结束。
[Signal Handler] 子进程PID:12346 以状态 0 退出。
子进程PID:12347 结束。
[Signal Handler] 子进程PID:12347 以状态 1 退出。
子进程PID:12348 结束。
[Signal Handler] 子进程PID:12348 以状态 2 退出。

代码解释:

  1. 创建多个子进程:循环调用fork()创建三个子进程,每个子进程有不同的工作时间。
  2. 信号处理函数sigchld_handler会被多次调用,以回收每个子进程的资源。
  3. 父进程执行其他任务:父进程在子进程运行期间继续执行其他任务,不会被阻塞。
  4. 无需显式等待:由于信号处理器已经负责回收子进程,父进程无需再次调用wait()waitpid()

6. 使用prctl设置子进程终止时的行为

在某些情况下,可以通过prctl系统调用设置子进程终止时的行为。例如,可以设置PR_SET_CHILD_SUBREAPER,使得特定的进程成为“子进程的收割者”,用于复杂的进程管理。

例子:设置PR_SET_CHILD_SUBREAPER
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <cstring>
#include <sys/prctl.h>int main() {// 将当前进程设置为子进程的收割者if (prctl(PR_SET_CHILD_SUBREAPER, 1) == -1) {std::cerr << "prctl failed: " << strerror(errno) << std::endl;return 1;}pid_t pid = fork();if (pid < 0) {std::cerr << "Fork failed!" << std::endl;return 1;}else if (pid == 0) {// 子进程执行的代码std::cout << "子进程PID:" << getpid() << " 启动。" << std::endl;sleep(2);std::cout << "子进程PID:" << getpid() << " 结束。" << std::endl;return 0;}else {// 父进程作为子进程的收割者,等待子进程结束std::cout << "父进程设置为子进程的收割者,等待子进程结束。" << std::endl;int status;pid_t terminated_pid = wait(&status);if (terminated_pid > 0) {if (WIFEXITED(status)) {std::cout << "子进程PID:" << terminated_pid << " 以状态 " << WEXITSTATUS(status) << " 退出。" << std::endl;}}}return 0;
}

代码解释:

  • prctl(PR_SET_CHILD_SUBREAPER, 1):将当前进程设置为子进程的收割者,使其能够回收其子孙进程的资源。
  • 这种设置在需要复杂的子进程管理,或在容器化环境中非常有用。
http://www.yayakq.cn/news/226013/

相关文章:

  • 重庆建站网络公司万网主机怎么上传网站
  • 招聘网站维护什么内容网站导航为什么用ul列表做
  • 如何通过建立网站赚钱网络营销推广方案ppt
  • 纯ajax网站如何做seoseo培训教程
  • 南昌做网站软件省机关事务局网站建设管理情况
  • 小程序商城哪家好又便宜aso优化什么意思是
  • 青岛建手机网站哪家好flash开发网站
  • 网站索引量怎么增加高校图书馆网站建设
  • wordpress调用 别的网站设计制作长方体形状的包装纸盒视频
  • 做网站需要走公司吗北京软件公司名称大全
  • 达内网站开发培训重庆网站建设快忻科技
  • 建设部职称证书查询官方网站什么叫高端网站定制
  • 山西建设银行招聘网站暴走漫画网站建设目的
  • 元氏网站建设唐山做网站的公司
  • 长春百度网站快速优化高端大气传媒公司名字
  • 网站建设价格由什么决定沈阳网站建设简维
  • 怎样做网站建设的程序广州seo推广营销
  • 襄阳网站建设价格网站上怎么做艳丽的色
  • 海南住房建设厅定额网站网页设计与网站开发试题答案
  • 南宁新技术产业建设开发总公司网站昆山智能网站开发
  • 中学生网站设计下载哈尔滨网络公司招聘
  • 医院网站开发公司深圳工业设计培训班
  • 搜狗做网站怎么样网络品牌是什么
  • 打开网址跳转到国外网站网络优化论文
  • 福鼎市建设局网站网页源代码看答案
  • 网站建设平台多少钱中国建设银行官方网站app下载
  • 太原建站模板厂家互联网推广渠道有哪些
  • 网站修改flashfxp上传多久生效怎么卸载电脑上wordpress
  • 新泰网站建设流程湖南长沙
  • 网站页面代码优化网站需要服务器吗