2009-09-11 38 views
3

我有一个程序,其中:推理PTHREAD问题()

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

在某些时候,线程(4)执行一个fork/exec来运行另一个应该连接到线程(2)正在监听的套接字的程序。有时这会失败或者花费时间过长,并且诊断极其困难。如果我对系统进行strace,看起来fork/exec已经工作,接受已经发生,新的线程(4)已经创建..但是在那个线程中没有任何反应(使用strace -ff,相关pid的文件是空白的)。

任何想法?

+0

你的主线程(1)在创建(2)和(4)后做了什么?它是永远等待(2)还是等到某种状况? – Los 2009-09-11 18:13:06

+0

(1)进入并等待键盘输入(使用与readline非常相似的东西),它形成命令,通过锁定的队列移交给(4)。 – pjc50 2009-09-14 09:51:21

回答

2

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

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

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

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

0

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

顺便说一句 - http://lists.samba.org/archive/linux/2002-February/002171.html似乎exec的pthread行为没有很好的定义,可能取决于你的操作系统。

你在fork和exec之间有任何代码吗?这可能是一个问题。

+0

该链接似乎描述了exec没有fork的问题,这可能不是一回事。 fork和exec之间没有太多的代码; fork/exec实际上是在Tcl解释器中完成的(使用tcl的“exec ...&”) 小型测试用例可能很困难,因为我无法可靠地用巨大的应用程序来重现它。 – pjc50 2009-09-11 16:05:13

+0

看看这个http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html。如果在那里没有你的代码,可能会有一些代码注入信息叉。请准备最小的例子。 – agsamek 2009-09-11 16:13:43

+0

>小型测试用例可能很困难,因为我无法可靠地重现它与巨大的应用程序。 --- pjc50:这是我们如何调试代码。我们不猜。我们跟踪错误。如果你有两种情况 - 一种是产生错误的大小,另一种是小的,那么你就接近找到它。只需删除大块代码并检查错误是否仍然存在。看看这里http://en.wikipedia.org/wiki/Binary_search_algorithm,做你的功课,让我们知道是什么问题。 – agsamek 2009-09-12 17:09:28

1

这看起来像是一个死锁状态。寻找阻塞函数,如accept(),问题应该在那里。

0

对于多线程和fork非常小心。大多数glibc/libstdC++是线程安全的。如果分叉线程以外的线程在fork执行分叉进程时持有一个锁,它将继承当前锁定状态下的互斥锁。新进程永远不会看到这些互斥锁解锁。欲了解更多信息,请参阅man pthread_atfork

-2

我刚刚陷入了同样的问题,最后发现 fork()重复了所有的线程。现在想象一下,什么是你的程序进程后()与所有的线程上运行双实例做...

以下规则是从"A Mini-guide regarding fork() and Pthreads"

1 - 你不想这样做。如果你需要fork(),那么: 只要有可能,fork()所有的 孩子在启动任何线程之前。

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

+0

这是不正确的。 fork不会复制所有线程,它只会复制调用线程,如下所述:http://www.opengroup.org/onlinepubs/000095399/functions/fork.html – nos 2010-08-31 21:22:07

+0

我还没有尝试过,但我会做。 – ern0 2010-09-01 09:16:49

+0

尝试并确认,fork()只能调用调用线程。 – ern0 2010-09-02 20:38:32