RXL
|
|
« : 16-01-2005 20:18 » |
|
Не подскажет ли кто идею, каким образом ожидать завершение нескольких потоков? Как я понимаю, аналога wait() в pthread нет, есть только pthread_join(), но она разрешает ожидать завершения только одного, указанного, потока.
Я пока нагородил такую конструкцию: каждому потоку у меня соответствует переменная, которую я перед pthread_create() устанавливаю в 1, и периодически просматриваю их: каждый поток, посредством ф-ии, устанавливаемой через pthread_cleanup_push(), по завершению устанавливает свою переменную в 0.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
npak
|
|
« Ответ #1 : 17-01-2005 10:17 » |
|
RXL, pthread_join ждёт ожидания потока. Если в момент вызова pthread_join поток уже завершился, то функция сразу же вернёт управление. Поэтому если у тебя есть несколько потоков, то можно делать последовательный join сначала к первому, затем ко второму и так далее. После того, как последний join вернёт управление, все потоки гарантированно закончатся. Пример из стандарта POSIX -- ожидание завершения двух потоков. typedef struct { int *ar; long n; } subarray; void * incer(void *arg) { long i; for (i = 0; i < ((subarray *)arg)->n; i++) ((subarray *)arg)->ar[i]++; } int main(void) | { int ar[1000000]; pthread_t th1, th2; subarray sb1, sb2; sb1.ar = &ar[0]; sb1.n = 500000; (void) pthread_create(&th1, NULL, incer, &sb1); sb2.ar = &ar[500000]; sb2.n = 500000; (void) pthread_create(&th2, NULL, incer, &sb2); (void) pthread_join(th1, NULL); (void) pthread_join(th2, NULL); return 0; | }
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #2 : 17-01-2005 15:01 » |
|
npak, это-то понятно. Я имею в виду ожидание завершения любого произвольного патока, когда остальные могут еще долго работать.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
npak
|
|
« Ответ #3 : 18-01-2005 08:35 » |
|
RXL,
смотри в сторону pthread_cond_wait (или pthread_cont_timedwait) и pthread_cond_signal
Функция pthread_cond_wait блокируется до срабатывания некоторого условия. Функция pthread_cond_signal это условие заставляет сработать.
Идея: создай некоторое глобальное условие или передай условие в функции потоков при инициализации.
Потоко-родитель после запуска потоков-детей блокируется на этом условии. Потоки-потомки перед окончанием своей работы вызывают pthread_cond_signal, чтобы уведомить родителя о своей "смерти". Потокок-родитель разблокируется сразу после того, как один из потомков завершит свою работу. Для верности стоит добавить pthread_cond_signal в обработчик завершения потока (pthread_cleanup_push), чтобы родитель получил уведомление об окончании потомка даже в случае аварийного завершения потока.
Предложенное решение гарантирует, что поток-родитель разблокируется при завершении произвольного потомка. Недостаток -- нет возможности получить информацию о том, кто из потомков завершился.
|
|
|
Записан
|
|
|
|
RXL
|
|
« Ответ #4 : 18-01-2005 11:53 » |
|
Вот что я нагородил: pthread_t thd0,thd1,thd2,thd3; int fin_flag=0; int live1_flag=1; int live2_flag=1; int live3_flag=1;
........ signal(SIGUSR1,&sig_usr1); ........ thd0=pthread_self(); pthread_create(&thd1,0,&thd1_func,0); pthread_create(&thd2,0,&thd2_func,0); pthread_create(&thd3,0,&thd3_func,0); while(!fin_flag) { if(!live1_flag) { pthread_join(thd1,0); // thread 1 stoped } if(!live2_flag) { pthread_join(thd2,0); // thread 2 stoped } if(!live3_flag) { pthread_join(thd3,0); // thread 3 stoped } tv.tv_sec=0; tv.tv_usec=100000; select(0,0,0,0,&tv); } if(live1_flag) { pthread_cancel(thd1); pthread_join(thd1,0); } if(live2_flag) { pthread_cancel(thd2); pthread_join(thd2,0); } if(live3_flag) { pthread_cancel(thd3); pthread_join(thd3,0); } .............
void sig_usr1(int sig) { }
void thd1_cleanup(void *arg) { live1_flag=0; pthread_kill(thd0,SIGUSR1); }
void* thd1_func(void *arg) { pthread_cleanup_push(&thd1_cleanup,0); .......... pthread_cleanup_pop(1); return 0; }
Кстати, никто не порекомендует литературу по POSIX, окромя самого стандарта?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #5 : 18-01-2005 12:13 » |
|
RXL, я не силён в программинге под *nix, но может тебе пригодится вот эта книга. Там есть целый раздел по программингу в *nix системах. Ещё есть вот эта, полностью посвящена программингу в никсах. Обе книги на русском языке.
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
RXL
|
|
« Ответ #6 : 18-01-2005 12:48 » |
|
MOPO3, спасибо. Только вторая ссылка не работает: The requested URL /test/shelek/linix.rar was not found on this server.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #7 : 18-01-2005 12:54 » |
|
Sorry вот тут нормально лежит обшибся я в написании названия файла
|
|
« Последнее редактирование: 18-01-2005 13:07 от MOPO3 »
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
npak
|
|
« Ответ #8 : 18-01-2005 13:17 » |
|
RXL, у меня есть книга под названием "PThreads для начинающих" (PThreads Primer). Правда, название сильно преуменьшает сложность книги, или автор очень высокого мнения о "начинающих". Тем не менее, читать можно. Местами довольно понятно Если нужно, могу открыть через веб, а ты или мороз выложите на сайт шелека.
|
|
|
Записан
|
|
|
|
MOPO3
Ай да дэдушка! Вах...
Команда клуба
Offline
Пол:
Холадна аднака!
|
|
« Ответ #9 : 18-01-2005 13:19 » |
|
npak, я выложить не смогу. Не имею доступа ни к фтп с книгами, ни к админской части сайта
|
|
|
Записан
|
MCP, MCAD, MCTS:Win, MCTS:Web
|
|
|
RXL
|
|
« Ответ #10 : 18-01-2005 19:28 » |
|
npak, спасибо. Судя по оглавлению, то что нужно.
MOPO3, у меня тож - видимо что-то поменялось. В ближайшее время выясню, а за одно и выложу все три книги на сайте.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
|