fork()的神秘pthread问题

时间:2009-09-11 15:09:15

标签: c++ posix pthreads

我有一个程序:

  • 有一个主线程(1),它启动服务器线程(2)和另一个(4)。
  • 服务器线程(2)执行accept(),然后创建一个新线程(3)来处理连接。

在某些时候,thread(4)执行fork / exec来运行另一个应该连接到线程(2)正在侦听的套接字的程序。偶尔这会失败或花费不合理的长时间,而且诊断起来非常困难。如果我strace系统,似乎fork / exec已经工作,接受已经发生,新线程(4)已经创建..但是该线程没有任何反应(使用strace -ff,相关pid的文件)是空白的。)

有什么想法吗?

5 个答案:

答案 0 :(得分:2)

我得出的结论可能是这种现象:

http://kerneltrap.org/mailarchive/linux-kernel/2008/8/15/2950234/thread

因为我们的开发系统很难触发错误,但通常由运行在大型共享计算机上的用户报告; forked应用程序也启动了一个JVM,它本身分配了很多线程。问题还与正在加载的机器和大量内存使用有关(我们有一台带有128Gb RAM和进程的机器可能是10-100G)。

我一直在阅读O'Reilly pthreads书,它解释了pthread_atfork(),并建议使用从启动子进程的主进程派生的“代理父进程”进程。它还建议使用预先创建的线程池。这两个看起来都是好主意,所以我要实现至少其中一个。

答案 1 :(得分:1)

看起来像死锁情况。寻找阻塞函数,比如accept(),问题就在那里。

答案 2 :(得分:0)

将代码减少到仍然具有行为的最小可能大小并在此处发布。要么你会找到答案,要么我们将能够追踪它。

BTW - http://lists.samba.org/archive/linux/2002-February/002171.html似乎exec的pthread行为定义不明确,可能取决于您的操作系统。

fork和exec之间有代码吗?这可能是个问题。

答案 3 :(得分:0)

对多个线程和fork非常小心。大多数glibc / libstdc ++都是线程安全的。如果分叉执行分叉进程时,除分叉线程之外的线程持有锁,则将继承处于当前锁定状态的互斥锁。新进程永远不会看到那些互斥锁被解锁。有关详细信息,请参阅man pthread_atfork

答案 4 :(得分:-2)

我遇到了同样的问题,最后发现 fork()复制了所有的线程。现在想象一下,你的程序在fork()之后执行什么操作,所有线程都运行双实例......

以下规则来自"A Mini-guide regarding fork() and Pthreads"

<击>   

1-你不想这样做。

     

2-如果你需要fork()那么:   尽可能,fork()所有你的   孩子在开始任何线程之前。   

编辑:试过,fork()不复制线程。