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