c++中的fork函数_Linux下使用fork创建多个子进程

本文通过一个实例分析了在C++中使用fork创建子进程时遇到的问题,即由于构造函数中子进程没有正确退出导致的递归创建过多子进程的情况。通过在子进程执行完后调用`exit(0)`解决问题,确保只创建预期数量的子进程。
摘要由CSDN通过智能技术生成

Nginx软件实现了一个master进程,多个worker子进程的运行模型。现在我打算用C++来实现这种模型,一开始我是这么实现的,先创建一个worker类,

class worker

{

public:

worker()

{

int pid = fork();

switch(pid)

{

case 0:

printf("[Worker]: Parent (%d) created child(%d). \n", getppid(), getpid());

// sleep for 2 seconds

sleep(2);

printf("[Worker]: with pid %d exit! \n", getpid());

break;;

case -1:

printf("[Worker]: Fork failed!\n");

break;

default:

break;

}

}

~worker()

{

printf("[Worker]: with pid %d destructed\n", getpid());

}

};

然后创建一个main函数,使用for循环去创建三个worker对象

int main()

{

std::vector<:unique_ptr>> workers;

printf("[Master]: Proc Start with pid %d! \n", getpid());

for (int i = 0; i < PROCESS_NUM; i++)

{

workers.push_back(std::make_unique());

}

}

看上去理所应当的应该创建三个子进程,每个子进程等待两秒后就退出了,然而打出来的日志却明显不是我们所要的,

[Master]: Proc Start with pid 7495!

[Worker]: Parent (7495) created child(7496).

[Worker]: Parent (7495) created child(7497).

[Worker]: Parent (7495) created child(7498).

[Worker]: with pid 7498 exit!

[Worker]: with pid 7497 exit!

[Worker]: with pid 7496 exit!

[Worker]: Parent (7496) created child(7500).

[Worker]: Parent (7497) created child(7499).

[Worker]: Parent (7496) created child(7501).

[Master]: Proc End with pid 7495!

[Worker]: with pid 7495 destructed

[Worker]: with pid 7495 destructed

[Worker]: with pid 7495 destructed

root@evan-VirtualBox:~/EvanWorkspace/sctp_socket/thundering_herd/build# [Worker]: with pid 7500 exit!

[Worker]: with pid 7499 exit!

[Worker]: with pid 7501 exit!

[Worker]: Parent (7500) created child(7502).

...

明显的创建了不止3个子进程,这是为什么呢?

原因就出在worker的构造函数中,当判断出来是当前的是子进程的时候,等待两秒后的结束语句是break。

子进程在fork函数调用完成后,相当于是从当前节点开始拷贝了一份代码在子进程中运行

例如子进程7496运行到break后,退出worker构造函数,返回main函数的for循环;

这个时候子进程7496的main函数喊剩余两次循环,所以7496作为父进程又创建了两个新的子进程7500/7501;

如此循环递归下去;

正确的方法是在worker的构造函数中判断出来是子进程之后,子进程的处理完成后调用exit(0)退出当前子进程,这样就能得到我们要的结果了。

worker()

{

int pid = fork();

switch(pid)

{

case 0:

printf("[Worker]: Parent (%d) created child(%d). \n", getppid(), getpid());

// sleep for 2 seconds

sleep(2);

printf("[Worker]: with pid %d exit! \n", getpid());

exit(0);;

case -1:

printf("[Worker]: Fork failed!\n");

exit(0);

default:

break;

}

}

打印的结果如下

[Master]: Proc Start with pid 7565!

[Worker]: Parent (7565) created child(7566).

[Worker]: Parent (7565) created child(7567).

[Worker]: Parent (7565) created child(7568).

[Worker]: with pid 7566 exit!

[Worker]: with pid 7567 exit!

[Worker]: with pid 7568 exit!

[Master]: Proc End with pid 7565!

[Worker]: with pid 7565 destructed

[Worker]: with pid 7565 destructed

[Worker]: with pid 7565 destructed

这里还有问题,看最后的几行打印,实际上这里调用的析构函数销毁的是主进程中三个worker对象 ;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值