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

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

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

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

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

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

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

неблокирующее присоединение к потоку? Я думал, что присоединение связано с блокировкой: s

Mladen Janković 16.09.2008 19:22
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
23
1
35 043
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

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

Ответ действительно зависит от того, почему вы хотите это сделать. Например, если вы просто хотите очистить мертвые потоки, вероятно, проще всего иметь поток «очистителя мертвых потоков», который зацикливается и соединяется.

Я не уверен, что именно вы имеете в виду, но предполагаю, что вам действительно нужен механизм ожидания и уведомления.

Вкратце, вот как это работает: вы ждете выполнения условия с таймаутом. Ваше ожидание закончится, если:

  • Истекло время ожидания, или
  • Если условие выполнено.

Вы можете сделать это в цикле и добавить больше интеллекта в вашу логику. Лучший ресурс, который я нашел для этого, связанный с Pthreads, - это этот учебник: Программирование потоков POSIX (https://computing.llnl.gov/tutorials/pthreads/).

Я также очень удивлен, увидев, что в Pthreads нет API для синхронизированного соединения.

Нет pthread_join с синхронизацией, но если вы ждете, что другой поток заблокирован по условиям, вы можете использовать pthread_cond_timed_wait с синхронизацией вместо pthread_cond_wait.

Если вы разрабатываете для QNX, вы можете использовать функцию pthread_timedjoin ().

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

Ответ принят как подходящий

Как отмечали другие, в стандартных библиотеках 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 для всех ваших потоков (завершенных или нет), поэтому вызов этого для всех ваших потоков не будет блокироваться и гарантирует выход потока (чистый или нет).

Это должно рассматриваться как «простой» обходной путь.

Это неверный ответ. Успешный вызов pthread_cancel в каждом потоке не гарантирует, что все потоки завершились. Возможно, они не достигли какой-либо точки отмены, или даже если они достигли, основной поток может быть запланирован первым и вернуться из main, убивая процесс, прежде чем другие потоки смогут завершить очистку ...

R.. GitHub STOP HELPING ICE 07.07.2011 07:32

Я думаю, что для этого ответа требуется pthread_join () после pthread_cancel (): «После завершения отмененного потока соединение с этим потоком с использованием pthread_join (3) получает PTHREAD_CANCELED в качестве статуса выхода потока. (Присоединение к потоку - единственный способ чтобы знать, что отмена завершена.) "

Zoltan K. 31.03.2019 20:59

Если вы запускаете свое приложение в 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, хотя и полезны.

ссылка на страницу руководства

Механизм pthread_join удобен, если он делает именно то, что вы хотите. Он не делает того, что вы не могли бы сделать сами, а там, где это не совсем то, что вы хотите, кодируйте именно то, что вы хотите.

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

Начните с изменения своего мышления. Застрял не поток, а то, что он делал.

Добавьте, пожалуйста, образец кода? У меня примерно такая же проблема, процесс вызывает два потока и должен завершиться только после выхода потоков - ни один из ответов здесь не объяснял, как сделать что-то похожее на функцию fork (). (Я добавил этот вопрос в избранное, он сообщит мне, как только вы ответите автоматически)

user649198 11.01.2012 03:37

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

David Schwartz 11.01.2012 03:41

Спасибо. Пример кода был бы полезен, но я мог бы попробовать поискать и в другом месте.

user649198 11.01.2012 03:45

Ваш вопрос просто "как мне чего-то ждать"?

David Schwartz 11.01.2012 03:51

Да; потоки posix (pthread_create и pthread_join), похоже, работает аналогично тому, что мне нужно, используя pthread_join ... теперь нет проблем. Спасибо за уделенное время.

user649198 11.01.2012 04:11

... ... или нет. Как я уже сказал, пример кода был бы полезен, они, кажется, просто выполняют успешный вызов pthread_join, но поток не завершает свою работу.

user649198 11.01.2012 04:47

@gry Вместо того, чтобы пытаться присоединиться к потоку, дождитесь завершения задания. Это сводит ваш вопрос к гораздо более простому - «как мне чего-то ждать». Ответ: используйте условные переменные.

David Schwartz 11.01.2012 05:08

Какую функцию мне следует использовать для работы с условными переменными? У вас есть справочная страница, название функции, пример, к которому можно обратиться? (как упоминалось ранее, я добавил этот вопрос в избранное, он сообщит мне, как только вы ответите автоматически)

user649198 11.01.2012 05:25

Другие вопросы по теме