Подтвердить что ты не робот

Неблокирующий pthread_join

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

Есть ли способ сделать неблокирующий pthread_join? Некоторое время по времени было бы неплохо.

что-то вроде этого:

foreach thread do
  nb_pthread_join();
    if still running
      pthread_cancel();

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

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

4b9b3361

Ответ 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

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