fork在多线程程序中

jim*_*imx 23 multithreading operating-system fork

我听说在程序中混合分叉和线程可能非常有问题,通常会产生神秘的行为,特别是在处理共享资源时,例如锁,管道,文件描述符.但我从未完全明白危险是什么以及何时会发生.如果具有该领域专业知识的人能够更详细地解释在这样的环境中编程时存在哪些陷阱以及需要注意什么,那将是很棒的.

例如,如果我想编写一个从各种不同资源收集数据的服务器,我认为一个解决方案是让服务器生成一组线程,每个popen调用另一个程序来完成实际工作,打开管道从孩子那里获取数据.这些线程中的每一个都响应它自己的工作,没有数据交换它们,并且当收集数据时,主线程有一个队列,这些工作线程只将结果放入队列.这个解决方案可能出现什么问题?

请不要通过"回答"我的示例场景来缩小您的答案范围.任何与示例无关但有助于提供简洁设计的建议,替代解决方案或体验都会非常棒!谢谢!

bdo*_*lan 17

当你运行一些线程时,分叉的问题是fork只复制调用它的一个线程的CPU状态.这就好像所有其他线程都会立即死亡,无论它们在哪里.

结果是没有释放锁,并且共享数据(例如malloc堆)可能已损坏.

pthread确实提供了pthread_atfork函数 - 理论上,你可以在分叉之前获取程序中的每个锁,之后释放它们,并且可能使它活着 - 但它有风险,因为你总是会错过一个.当然,其他线程的堆栈也不会被释放.


180*_*ION 0

这确实很简单。多线程和进程的问题总是由共享数据引起的。如果没有共享数据,那么就不可能出现问题。

在您的示例中,共享数据是主线程拥有的队列 - 任何潜在的争用或竞争条件都会在这里出现。“解决”这些问题的典型方法涉及锁定方案 - 工作线程将在插入任何数据之前锁定队列,而主线程将在删除队列之前锁定队列。