7

可能重复:
多线程程序中的分叉

如果我有一个使用 fork() 并且可能被开发为多线程的应用程序,那么安全编程此类应用程序需要考虑哪些经验法则/指南?

4

2 回答 2

4

根据各种互联网文章(例如(http://www.linuxprogrammingblog.com/threads-and-fork-think-twice-before-using-them,fork in multi-threaded program )) ,基本的经验法则是:

  1. (主)进程 [0] 单线程 --> fork() --> (子)进程 [1] 多线程好的!
    如果Process[1]崩溃或内存混乱,它不会触及Process[0]的地址空间(除非您使用共享 R/W 内存......但这是它自己的另一个主题)。
    默认情况下,在 Linux 中,所有fork()ed内存都是Copy On Write。鉴于Process[0]是单线程的,当我们调用fork()时,所有可能的互斥原语通常应该处于解锁状态。

  2. (主)进程 [0] 多线程 --> fork() --> (子)进程 [1] 单/多线程糟糕!
    如果你fork()一个多线程进程,你的互斥锁和许多其他线程同步原语可能在 Process[1] 中处于未定义状态。您可以使用pthread_atfork()解决,但如果您使用库,您不妨掷骰子并希望幸运。因为通常你不(想)知道库的实现细节。

fork()进入多线程进程的优点是您可以更快地操作/读取/聚合数据(在子进程中),而不必关心您从(主)中fork()的进程的稳定性。如果您的主进程具有大量内存的数据集并且您不想复制/重新加载它以安全地处理另一个进程(子进程)中的数据,这将非常有用。这样,原始过程是稳定的,并且独立于数据聚合/操作过程(fork()ed)。

当然,这意味着原始进程通常会比以多线程方式开发时要慢。但同样,这是您可能希望为提高稳定性而付出的代价。

如果您的主进程是多线程的,请不要使用fork()。以稳定的方式实现它将是一个适当的混乱。

干杯

于 2012-10-13T00:10:27.640 回答
-1

在 Linux 上,线程是根据进程来实现的。换句话说,线程实际上只是一个fork()共享内存,而不是完全的写时复制内存。这意味着,当您fork()在线程(主线程或其他线程)中使用时,您最终会复制所有线程的整个共享内存空间,以及您调用的线程的线程特定存储fork()

现在所有这些听起来都不错,但这并不意味着这将发生或运作良好。如果您想创建一个克隆进程,请在启动任何其他线程之前尝试执行一个 fork,然后使用只读虚拟内存使 fork 进程与当前内存值保持同步。

所以虽然它可能有效,但我只是建议测试,并尝试先找到另一种方法。并为很多事情做好准备:

Segmentation fault
于 2012-10-13T00:25:53.260 回答