网上很多基于C语言的开源代码,会涉及很多全局变量,当需要修改源码支持并发时,使用多线程处理很麻烦时,会考虑使用fork进行多进程处理,简单整理了一下fork函数的使用及僵尸进程处理,代码如下:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
//gcc fork_test.c -o fork_test
int g_child_process_count = 2;
void test()
{
printf("I am the child process<%d> begin ... ...\n", getpid());
sleep(10);
printf("I am the child process<%d> end ... ...\n", getpid());
}
void signal_handler(int signum)
{
printf("I am the parent process<%d>, catch signal:%d\n", getpid(), signum);
pid_t pid;
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
{
g_child_process_count--;
printf("I am the parent process<%d>, my child process<%d> is exit\n", getpid(), pid);
}
return;
}
int main()
{
//处理僵尸进程
//signal(SIGCHLD, SIG_IGN); //方法一:忽略
signal(SIGCHLD, signal_handler); //方法二:信号处理函数
int i = 0;
for (i = 0; i < 2; i++)
{
// fork一次调用,返回两次
// 1)在父进程中,fork返回新创建子进程的进程ID
// 2)在子进程中,fork返回0
// 3)如果出现错误,fork返回一个负值
pid_t fpid = fork();
if (fpid < 0)
{
printf("error in fork!");
}
else if (fpid == 0)
{
printf("I am the child process<%d>, my parent<%d>\n", getpid(),getppid());
test();
exit(0);
}
else
{
printf("I am the parent process<%d>\n", getpid());
}
}
do
{
printf("I am the parent process<%d>, waiting child to exit ... ...\n", getpid());
sleep(1);
} while (g_child_process_count > 0);
printf("I am the parent process<%d>, all child is exit\n", getpid());
return 0;
}
编译:gcc fork_test.c -o fork_test
测试:./fork_test
运行结果:
注意:如果去掉signal(SIGCHLD, signal_handler)或者signal(SIGCHLD, SIG_IGN)运行后会出现僵尸进程