Реальный вопрос не в том, как поток данных должен отправлять сигнал, а в том, как основной поток должен принимать сигнал. Мой любимый метод - использовать socketpair () для создания локального соединения с сокетом, а затем передать один сокет дочернему потоку, а другой сокет - основному. Затем два потока могут использовать сокет-соединение для связи друг с другом. В вашем случае все, что вам нужно, это чтобы дочерний поток отправлял байт в сокет (или просто закрывал свой дескриптор файла сокета) непосредственно перед его выходом, и этого было бы достаточно, чтобы вырвать основной поток из select () или poll () или что бы он ни блокировал, и пусть он знает, что дочерний поток завершил свою задачу.
Обратите внимание, что основной поток должен по-прежнему вызывать join () для идентификатора потока дочернего потока (после того, как он получит сигнал уходящего ребенка), чтобы убедиться, что дочерний поток действительно действительно мертв, прежде чем освобождать любые ресурсы ... в противном случае вы рискуете состязанием основного потока, освобождающего ресурс после того, как дочерний поток дал сигнал, но до завершения процедур очистки потока.