当父进程具有许多线程,套接字和IPC时,在派生(子)进程中调用system() [英] Call system() inside forked (child) process, when parent process has many threads, sockets and IPC

查看:102
本文介绍了当父进程具有许多线程,套接字和IPC时,在派生(子)进程中调用system()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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.

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

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

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

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?

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

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.

推荐答案

诸如TCP套接字之类的文件描述符(也称为fds)是通过fork继承的.文件或文件后面"的文件或设备通常保持打开状态并可以使用,直到最后一个文件描述符在进程终止时关闭或关闭为止.因此,SIGKILL'ing子级不会影响与父级共享的TCP套接字.

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.

但是,只有fork()ing线程在子级中执行.其他控制线程不会被复制.您的情况如下所示:

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

调用exec会将PID 101过程映像替换为某些文本的main()(并关闭所有标记为FD_CLOEXEC的文件描述符).相比之下,调用system("whatever")可能会至少产生两个进程:(大)子级/bin/sh和(大)子级"whatever".

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".

很容易混淆自己混合线程,派生和共享资源,尤其是如果将诸如system()之类的旧的,旧的接口扔进了混合中.慢慢进行,在不需要的时候明确丢弃不需要的资源,并一次对一件事进行故障排除.

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.

这篇关于当父进程具有许多线程,套接字和IPC时,在派生(子)进程中调用system()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆