当fork进程有多个线程,套接字和IPC时,在forked(子)进程内调用system()

时间:2015-09-03 02:20:42

标签: linux multithreading sockets unix fork

我有一个有很多线程的程序。有些线程是TCP服务器......每个服务器都会触发新线程来处理任何新连接。

在一个处理单个客户端的线程中,我调用fork()。子进程调用setpgid()(创建一个新组),然后调用system()(C / C ++标准库的函数)。父进程不断进行小睡(usleep()函数)并检查时间限制。如果在子进程从system()返回之前超过了时间限制,则父SIGKILL表示子进程。

我正在使用:Linux(Ubuntu),pthreads等。只有C / C ++标准库!

我的问题:子进程上的所有线程和TCP套接字会发生什么?这些东西是从父进程继承的吗?子和父是否同时运行所有这些线程和TCP服务器?对我来说没有任何意义......当父母SIGKILLs生孩子时,套接字是否只能在孩子内部或父母内部关闭?

目前,我实际上使用exec()来清理子进程的整个映像,但是如果它安全的话,我宁愿直接调用system()。

1 个答案:

答案 0 :(得分:3)

TCP套接字等文件描述符(a.k.a. fds)通过fork继承。它们后面的文件或设备通常保持打开和可维护状态,直到它的最后一个文件描述符在进程终止时关闭或解除。因此,SIGKILL的子节点不会影响与父节点共享的TCP套接字。

然而,只有fork()线程在子进程中执行。不复制其他控制线程。你的情况看起来像这样:

+-- PID 100 -------------+ # parent
| fds: 0, 1, 2, 3 ... N  | # fds: stdin, stdout, stderr, socket ... socket
| threads:               |
|      0 (main)          |
|      1 (tcp server)    |
|      2 (forky)  ---------(fork(2))-+
|      ...               |           |
|      N (tcp server)    |           |
+------------------------+           |
                                     |
                                     |
                     +-- PID 101 -------------+ # child
                     | fds: 0, 1, 2, 3 ... N  | # fds: inherited
                     | threads:               |
                     |      0 (copy of forky) | # will exec() ?
                     +------------------------+

调用exec将用一些文本main()替换PID 101过程映像(并关闭标记为FD_CLOEXEC的任何文件描述符)。相反,调用system("whatever")可能会产生至少两个进程:一个(大)子/bin/sh和一个(伟大的)孙子“无论如何”。

混淆线程,分支和共享资源很容易混淆自己,特别是如果将旧的旧接口(例如system())混合在一起。慢慢来,明确地丢弃不需要的资源,并一次解决一件事。