Вызвать system() внутри разветвленного (дочернего) процесса, когда у родительского процесса много потоков, сокетов и IPC
У меня есть программа, которая имеет много тем. Некоторые потоки являются TCP-серверами... Каждый сервер запускает новые потоки для обработки любых новых соединений.
Внутри одного из потоков, который обрабатывает один клиент, я вызываю fork(). Дочерний процесс вызывает setpgid () (для создания новой группы), а затем system () (функция стандартной библиотеки C/C++). Родительский процесс продолжает дремать (функция usleep ()) и проверяет ограничение по времени. Если ограничение по времени превышено до того, как дочерний процесс возвращается из system (), родительский SIGKILLs дочерний.
Я использую: Linux (Ubuntu), pthreads и т. Д. Ничего, кроме стандартной библиотеки C/C++!
Мои вопросы: что происходит со всеми потоками и сокетами TCP на дочернем процессе? Унаследованы ли эти вещи от родительского процесса? Будут ли и дочерний, и родительский запускать все эти потоки и TCP-серверы одновременно? Это не имеет смысла для меня... А когда родительский SIGKILLs дочерний, сокеты будут закрыты только внутри дочернего элемента или также в родительском?
В настоящее время я на самом деле использую exec() для очистки всего изображения дочернего процесса, но я бы предпочел вызвать system () напрямую, если это безопасно.
1 ответ
Файловые дескрипторы (также известные как fds), такие как сокеты TCP, наследуются через форк. Файл или устройство, находящиеся "за ними", обычно остаются открытыми и работоспособными до тех пор, пока последний дескриптор файла не будет закрыт или закрыт при завершении процесса. Таким образом, SIGKILL'ing дочерний элемент не повлияет на сокеты 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
заменит изображение процесса PID 101 текстом main()
(и закройте все файловые дескрипторы, помеченные как FD_CLOEXEC). призвание system("whatever")
напротив, вероятно, породил бы по крайней мере еще два процесса: (великий) ребенок /bin/sh
и (великий) внук "что угодно".
Очень легко смешивать себя, смешивая потоки, вилки и общие ресурсы, особенно если старые, старые интерфейсы, такие как system()
брошены в смесь. Идите медленно, явно отбрасывайте ресурсы, которые вам не нужны, когда они вам не нужны, и устраняйте неисправности по одной вещи за раз.