Как правильно обрабатывать сигналы при использовании шаблона рабочего потока? - PullRequest
3 голосов
/ 18 мая 2010

У меня есть простой сервер, который выглядит примерно так:

void *run_thread(void *arg) {
    // Communicate via a blocking socket
}

int main() {
    // Initialization happens here...

    // Main event loop
    while (1) {
        new_client = accept(socket, ...);
        pthread_create(&thread, NULL, &run_thread, *thread_data*);
        pthread_detach(thread);
    }

    // Do cleanup stuff:
    close(socket);
    // Wait for existing threads to finish
    exit(0); 
)

Таким образом, при получении SIGINT или SIGTERM мне нужно выйти из цикла основного события, чтобы перейти к коду очистки. Более того, наиболее вероятно, что главный поток ожидает вызова accept (), поэтому он не может проверить какую-то другую переменную, чтобы определить, должна ли она прерваться;.

Большинство советов, которые я нашел, были примерно такими: http://devcry.blogspot.com/2009/05/pthreads-and-unix-signals.html (создание специального потока обработки сигналов, чтобы перехватывать все сигналы и обрабатывать их). Тем не менее, это часть обработки, которую я не могу по-настоящему обернуть: как я могу сказать основному потоку вернуться из вызова accept () и проверить внешнюю переменную, чтобы увидеть, должна ли она сломаться;

Ответы [ 2 ]

2 голосов
/ 18 мая 2010

Обычно я жду select(listeninig-socket-here), а не accept(). accept() - это обычно метод, при котором программа не тратит много времени на ожидание. И когда я жду в select() и сигнал SIGTERM отправляется в этот поток (в вашем случае это основной поток), я выхожу из этого select и select возвращает interrupted system call.

1 голос
/ 18 мая 2010

Я второй skwllsp , по его мнению, вы должны использовать select call вместо accept. Но мое дополнительное предложение заключается в том, что вы следуете совету блога, чью ссылку вы разместили, и создаете отдельный поток обработки сигналов и игнорируете сигналы во всех других потоках. Затем, когда сигнал получен в потоке обработки сигналов, используйте pthread_cancel для отмены других потоков. Когда вы используете pthread_cancel, если поток, который отменяется, находится в точке отмены (выберите один из них), он появится и войдет в ваш обработчик, и вы сможете очистить и выйти из потока.

Вы можете найти больше информации об этом здесь , здесь и здесь

...