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