25

我听说在程序中混合分叉和线程可能会产生很大的问题,通常会导致神秘的行为,尤其是在处理共享资源时,例如锁、管道、文件描述符。但我从来没有完全理解危险到底是什么,什么时候会发生。如果有该领域专业知识的人能够更详细地解释什么是陷阱以及在这样的环境中编程时需要注意什么,那就太好了。

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

请不要仅通过“回答”我的示例场景来缩小您的答案。任何与示例无关但有助于提供简洁设计的建议、替代解决方案或经验都会很棒!谢谢!

4

2 回答 2

20

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

这样做的结果是锁没有被释放,并且共享数据(例如 malloc 堆)可能已损坏。

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

于 2009-08-05T20:33:21.370 回答
0

这真的很简单。多线程和多进程的问题总是来自共享数据。如果没有共享数据,则不会出现可能的问题。

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

于 2009-08-05T20:22:34.230 回答