Pthread_join (): сборщик ресурсов: ожидание нескольких потоков для выхода - PullRequest
0 голосов
/ 13 апреля 2011

Я программирую параллельное (многопоточное) серверное приложение - конечно же, используя pthread! - когда я столкнулся с проблемой с pthread_join, мое приложение было shuch (псевдокод):

/* Sheduler thread */
while (1) {

   c = get_client();
   r = get_resource();

   communication.c = c;
   communication.r = r;

   pthread_create( clnt_tid, null, clnt_fn, communication);
   resource_alloc_list_add(clnt_tid, r);

}

/* resources Collector thread */
while(!rs_alloc_list_is_empty()) {

   e = get_elt(rs_alloc);
   pthread_join(e.clnt_tid, retour);
   free_rs(e.r);
}
.........

проблема в том, что не существует неблокирующего вызова pthread_join - он есть, но он не переносим - и pthread_join не может присоединиться к какому-либо потоку, как wait (), в процессе программирования. Таким образом, если поток rsc_collector ожидает выхода одного клиентского потока, чтобы вернуть выделенный ресурс, и до того, как это произойдет, все другие потоки вышли, тогда их ресурс будет заблокирован - и поток планировщика не сможет обслуживать другого клиента - до первого нить прекращает свою работу. Можете ли вы сказать мне возможное решение этой проблемы?

РЕДАКТИРОВАТЬ:

Я буду более конкретен, я программирую локальную систему управления ресурсами (lrms) или систему выполнения удаленных программ, есть три разные программы: клиент pg, сервер pg и планировщик pg, клиент связывается с планировщиком и дождитесь, пока планировщик pg выделит ему незанятый сервер, чтобы он мог после отправки выполнить свою работу на удаленном сервере. sched pg поставит клиентский адрес в очередь клиентов. с другой стороны, сервер pg отправляет регистрационное сообщение планировщику и ожидает задания, планировщик ставит в очередь адрес сервера в очереди ресурсов (то есть под ресурсом подразумевается удаленный сервер, а не ресурсы, выделенные потоку системой). планировщик pg состоит из трех основных потоков:

  • main_thread: список сокетов, связанных в хорошо известном порту. получает и ставит в очередь требования и регистрации (другими словами, Производитель)
  • scheduler_thread: потребитель, снимающий с очереди адрес, получает сервер (исключает адрес сервера), создает поток клиента, сохраняет распределение клиент / сервер. и включите.
  • thread_collector thread: дождитесь завершения клиентских потоков, чтобы вернуть выделенный ресурс. Я подчеркиваю [*], чтобы создать специальный поток для сбора ресурсов, потому что это очень важно для правильного функционирования системы.

Примечание:

  • клиентский поток получает копию ресурса (сервера), а не оригинал.
  • [*] если я исключу этот поток и позволю каждому клиенту освободить свой ресурс (адрес удаленного сервера), поэтому в некоторых случаях, когда поток клиента падает перед вызовом функции free, ресурс теряется навсегда. .. поэтому я не рискну отдавать ресурсы под полный контроль над потоками клиентов.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2011

Как говорил ранее Алексей, функция потока может выделять и освобождать свои ресурсы.Вы также можете использовать pthread_cleanup_push и pop, если вам нужен метод, который может обрабатывать отмену.

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

Надеемся, что ваш поток коллектора не вращается непрерывно, что потребляет ресурсы.

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

0 голосов
/ 13 апреля 2011

Я бы порекомендовал сделать необходимую очистку в выходных потоках, а не в специальной ветке коллектора.В частности, локальные данные потока, созданные с помощью pthread_key_create(), могут иметь связанный вызов деструктора, вызываемый при выходе из потока.Этот деструктор может освободить ресурс (ы) приложения, связанный с потоком;самый простой способ - сохранить указатель на ресурс (ы) в специфичном для потока слоте (см. pthread_set_specific()), и в этом случае указатель будет автоматически отправлен деструктору.Поток коллектора все еще может вызывать pthread_join(), если потоки создаются и уничтожаются все время;хотя в качестве альтернативы вы можете создать поток в отдельном состоянии или вызвать pthread_detach() после создания.

Также посмотрите на аналогичный вопрос , заданный ранее.

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