остановка клиент-серверной программы - PullRequest
0 голосов
/ 10 февраля 2012

Я прошу прощения за основность этого вопроса, но у меня есть проблема здесь. У меня есть клиент-серверная программа. Я не знаю заранее, сколько связей придет, но они не бесконечны. И в конце, после того, как все соединения закрыты, выводятся некоторые результаты. Но проблема, с которой я сталкиваюсь, заключается в том, что прием соединений находится в бесконечном цикле while, как он останавливается для вывода результата.

Спасибо

Ответы [ 4 ]

1 голос
/ 10 февраля 2012

Обработка EINTR при ошибке от accept(2) с завершением программы и нажатием ^C обычно работает.

1 голос
/ 10 февраля 2012

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

Все, что нужно, требует просмотра используемого вами кода.

0 голосов
/ 20 февраля 2012

Хотя мой опыт работы с Windows NT, «имена» функций - это имена, которые присваивают имена общим функциям потоков или процессам, которые должны быть доступны в любой многопоточной среде.

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

// child thread

terminate_condition=FALSE;
while (!terminate_condition)
{
  // accept connections   
}
child_thread_done=TRUE;
// output results
exit_thread ();

// main thread

child_thread_done=FALSE;
child_thread=create_thread (...);

// monitor connections to determine when done

terminate_condition=TRUE;
while (!child_thread_done)
{
  sleep (1);
}
// or maybe output results here?
exit_process ();

Это решение с контролируемым завершением требует, чтобы только один поток записывал в логическое значение child_thread_done, а любой другой поток только читал.

Или

// child thread

while (1)
{
  // accept connections
}

// main thread

child_thread=create_thread (...);

// monitor connections to determine when done

kill_thread (child_thread);
// output results
exit_process ();

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

Если есть много дочерних потоков, работающих с соединениями, необходим механизм синхронизированного завершения: либо структура с таким количеством членов, сколько имеется дочерних потоков (завершающий поток устанавливает свой «завершенный» логический значение равным true, завершается, и основной поток отслеживает структура, гарантирующая, что все дочерние «завершенные» логические значения являются истинными перед продолжением) или счетчик, содержащий число работающих дочерних потоков (когда дочерний процесс собирается завершиться, он получает исключительный контроль над счетчиком с помощью спин-блокировки, уменьшает его и освобождает блокировка перед завершением: основной поток ничего не делает, пока счетчик не содержит ноль).

0 голосов
/ 10 февраля 2012

Вы можете установить обработчик для сигнала SIGTERM, который установит глобальную переменную volatile sig_atomic_t, и проверить эту переменную в цикле мультиплексирования (вероятно, около poll или select). Помните, что обработчики signal не могут вызывать много функций (только async-signal-safe ).

Приятный отлов SIGTERM ожидается от большинства серверов Linux или Posix.

Вы можете использовать библиотеку обработки событий, такую ​​как libev, libevent и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...