pthreads: как обрабатывать сигналы в главном потоке, который создает другие потоки? (показан конкретный код) - PullRequest
4 голосов
/ 11 декабря 2010

У меня есть основной поток, который остается в основной функции, то есть я не создаю его специально, как в pthread_create, потому что это не обязательно. Этот поток открывает файл, затем создает другие потоки, ждет, пока они завершат свою работу (т. Е. Выполняет соединение), очищает все (указатели, семафоры, условные переменные и т. Д.).

Теперь я должен применить этот код к блоку SIGINT:

sigset_t set; 
int sig; 
sigemptyset(&set); 
sigaddset(&set, SIGINT); 
pthread_sigmask(SIG_BLOCK, &set, NULL); 

while (1) { 
        sigwait(&set, &sig); 
        switch (sig) { 
                case SIGINT: 
                        /* handle interrupts */ 
                        break; 
                default: 
                        /* unexpected signal */ 
                        pthread_exit((void *)-1); 
        } 
}

и там написано Вы должны использовать функцию main (), чтобы запустить потоки N + 1 и дождаться их завершения. Если в программу поступает сигнал SIGINT, он должен обрабатываться главным потоком, чтобы корректно завершить работу программы и ее потоков

Я сомневаюсь, как мне поставить этот код? Это неправильно, чтобы поместить его в фоновый поток, созданный в main ()? Поскольку у меня уже есть блок с флагом выхода, который создает и присоединяет все остальные потоки, поэтому я не понимаю, идет ли этот код точно в основную функцию, где все делается / вызывается для запуска программы. Если я добавлю его в поток с этим кодом и обработчиком для очистки, это будет считаться занятым ожиданием?

1 Ответ

4 голосов
/ 11 декабря 2010

«Это говорит»?Что говорит?Домашнее задание?

Первое, что вы должны понять о программировании с потоками и сигналами, это то, что у вас очень мало контроля над тем, в какой поток доставляется сигнал.Если ваш основной поток хочет получить сигнал, он должен заблокировать сигнал перед созданием любых новых потоков и, возможно, разблокировать его после завершения их создания, чтобы гарантировать, что сигнал не будет доставлен им.

Однако , если вы следуете рекомендациям для обработчиков сигналов, вероятно, не имеет значения, какой поток обрабатывает сигнал.Все, что нужно сделать обработчику сигнала, это установить глобальный флаг или записать байт в канал (в зависимости от того, что лучше всего работает, чтобы основной поток заметил, что сигнал произошел. (Обратите внимание, что вы не можете использовать переменные условия или любые другиеблокировка примитивов из обработчиков сигналов!) Как и в фрагменте кода в вашем вопросе, блокировка сигнала и использование sigwait также возможны (опять же, имейте в виду, что его нужно заблокировать в всех потоках),но большинство программ не могут позволить себе останавливаться и ждать только сигналов, им также нужно ждать условных переменных и / или ввода из файлов. Один из способов решения этой проблемы - создать выделенный поток для вызова sigwait, ноэто довольно расточительно. Лучшее решение, если вы уже используете select, это переключиться на pselect, который может ожидать сигналы, а также события дескриптора файла (в то же время).

Вместо того, чтобы спрашивать нас об ответах (которые в любом случае было бы трудно дать, не видя полной программы, с которой вы пытаетесь работать), yлучше бы тебе было по-настоящему понять тонкости сигналов с потоками.

...