Call system() inside forked (child) process, when parent process has many threads, sockets and IPC

五迷三道 提交于 2020-01-15 15:08:12

问题


I have a program that have many threads. Some threads are TCP servers... Each server fires new threads to handle any new connections.

Inside one of the threads that handles a single client, I call fork(). The child process calls setpgid() (to create a new group) and then system() (the function of C/C++ standard library). The parent process keeps taking naps (usleep() function) and checking a time limit. If the time limit is exceeded before child process returns from system(), the parent SIGKILLs the child.

I'm using: Linux (Ubuntu), pthreads, etc. Nothing but C/C++ standard library!

My questions: what happens with all the threads and TCP sockets on the child process? Are these things inherited from the parent process? Will both child and parent run all these threads and TCP servers simultaneously? It would make no sense to me... And when parent SIGKILLs child, will the sockets be closed only inside child, or also in the parent?

Currently, I'm actually using exec() to clean the whole image of the child process, but I'd rather call system() directly if it's safe.


回答1:


File descriptors (a.k.a. fds) such as TCP sockets are inherited across a fork. The file or device "behind" them generally remains open and serviceable until the last file descriptor to it is closed or dismissed at process termination. Thus SIGKILL'ing the child won't affect the TCP sockets shared with the parent.

Only the fork()ing thread is executing in the child, however. The other threads of control are not copied. Your situation looks something like this:

+-- 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() ?
                     +------------------------+

Calling exec will replace the PID 101 process image with some text's main() (and close any file descriptors marked FD_CLOEXEC). Calling system("whatever"), by contrast, would probably spawn at least two more processes: a (grand)child /bin/sh and a (great) grandchild "whatever".

It's very easy to confound yourself mixing threads, forks, and shared resources, especially if old, old interfaces like system() are thrown into the mix. Go slowly, explicitly discard resources you don't need when you don't need them, and troubleshoot one thing at a time.



来源:https://stackoverflow.com/questions/32365987/call-system-inside-forked-child-process-when-parent-process-has-many-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!