Linux/POSIX:为什么 fork() 不分叉 *所有* 线程

Linux/POSIX: Why doesn't fork() fork *all* threads

众所周知,在POSIX下创建新进程的默认方式是使用fork()(在Linux下这内部映射到clone(...)

我想知道的是:众所周知,当一个人打电话给 fork() "The child process is created with a single thread--the one that called fork()" (参见https://linux.die.net/man/2/fork)。如果例如其他线程当前持有锁,这当然会导致问题。对我来说,不分叉进程中存在的所有线程,直觉上感觉就像 "leaky abstraction".

所以我想知道:为什么子进程中只会存在调用fork()的线程,而不是进程的所有个线程?这有充分的技术原因吗?

我知道 Multithreaded fork 上有一个相关问题,但那里给出的答案没有回答我的问题。

这两种可能性中:

  • 只有调用fork()的线程在子进程运行中继续

    缺点:如果另一个线程持有内部资源(如锁),它将不会被释放。

  • fork()后,所有线程都复制到子进程

    缺点:与外部资源交互的线程继续 运行 并行。如果一个线程正在将数据附加到一个文件:现在它发生了两次。

两者都不好,但第一个选择只会使新的子进程死锁,而第二个选择会导致进程外部损坏。这可以描述为 "bad".

POSIX 确实标准化了 pthread_atfork 以尝试在第一种情况下允许自动清理,但是 it cannot possibly work.

tl;dr 不要同时使用线程和叉子。如果必须,请使用 posix_spawn