Неблокирующий pthread_join
Я кодирую завершение многопоточного сервера. Если все идет так, как и все потоки, выходящие сами по себе, но есть небольшая вероятность того, что поток застрянет. В этом случае было бы удобно иметь не- -блочное соединение, чтобы я мог сделать.
Есть ли способ сделать неблокирующий pthread_join?
Некоторое время по времени было бы неплохо.
что-то вроде этого:
foreach thread do
nb_pthread_join();
if still running
pthread_cancel();
Я могу подумать о большем числе случаев, когда полезно использовать неблокирующее соединение.
Как кажется, такой функции нет, поэтому я уже закодировал обходной путь, но это не так просто, как хотелось бы.
Ответы
Ответ 1
Как отмечали другие, в стандартных библиотеках pthread нет неблокирующего pthread_join.
Однако, учитывая вашу заявленную проблему (пытаясь гарантировать, что все ваши потоки вышли из выключения программы), такая функция не нужна. Вы можете просто сделать это:
int killed_threads = 0;
for(i = 0; i < num_threads; i++) {
int return = pthread_cancel(threads[i]);
if(return != ESRCH)
killed_threads++;
}
if(killed_threads)
printf("%d threads did not shutdown properly\n", killed_threads)
else
printf("All threads exited successfully");
Нет ничего плохого в вызове pthread_cancel для всех ваших потоков (завершено или нет), поэтому вызов, который для всех ваших потоков не будет блокироваться и будет гарантировать выход потока (чистый или нет).
Это должно квалифицироваться как "простое" обходное решение.
Ответ 2
Если вы используете приложение на Linux, вам может быть интересно узнать, что:
int pthread_tryjoin_np(pthread_t thread, void **retval);
int pthread_timedjoin_np(pthread_t thread, void **retval,
const struct timespec *abstime);
Будьте осторожны, так как суффиксом это говорит, "np" означает "не переносимый". Они не являются стандартом POSIX, расширениями gnu, полезными.
ссылка на страницу руководства
Ответ 3
Механизм "pthread_join" - это удобство, которое можно использовать, если это происходит именно так, как вы хотите. Он не делает ничего, что вы не могли бы сделать сами, и где это не совсем то, что вы хотите, код именно то, что вы хотите.
Нет реальной причины, по которой вам действительно нужно заботиться о том, прекратился ли поток или нет. Что вы заботитесь о том, завершена ли работа, выполняемая потоком. Чтобы сказать это, попросите поток сделать что-то, чтобы указать, что он работает. Как вы это делаете, это зависит от того, что идеально подходит для вашей конкретной проблемы, которая сильно зависит от того, что делают потоки.
Начните с изменения мышления. Это не поток, который застревает, это то, что делал поток, который застревает.
Ответ 4
Если вы разрабатываете QNX, вы можете использовать функцию pthread_timedjoin().
В противном случае вы можете создать отдельный поток, который будет выполнять pthread_join() и предупредить родительский поток, например, сигнализируя о семафоре, что дочерний поток завершается. Этот отдельный поток может возвращать то, что получает от pthread_join(), чтобы родительский поток определял не только, когда ребенок завершает, но и какое значение он возвращает.
Ответ 5
Ответ действительно зависит от того, почему вы хотите это сделать. Например, если вы просто хотите очистить мертвые потоки, возможно, проще всего использовать поток "мертвой нити", который петли и соединяется.
Ответ 6
Я не уверен, что именно вы имеете в виду, но я предполагаю, что вам действительно нужен механизм ожидания и уведомления.
Короче говоря, вот как это работает: вы ждете условия, удовлетворяющие тайм-ауту. Ваше ожидание закончится, если:
- Время ожидания, или
- Если условие выполнено.
Вы можете получить это в цикле и добавить в свою логику еще больше интеллекта. Лучший ресурс, который я нашел для этого, связанный с Pthreads, - это учебник:
Программирование потоков POSIX (https://computing.llnl.gov/tutorials/pthreads/).
Я также очень удивлен, увидев, что нет API для включения времени в Pthreads.
Ответ 7
Не существует timed pthread_join
, но если вы ожидаете, что другой поток заблокирован на условиях, вы можете использовать timed pthread_cond_timed_wait
вместо pthread_cond_wait
Ответ 8
Вы можете нажать байт в трубу, открытую как неблокирующую, чтобы сигнализировать о другом потоке, когда это делается, а затем использовать неблокируемое чтение для проверки состояния канала.