Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: pthread: ожидание нескольких потоков  (Прочитано 21320 раз)
0 Пользователей и 1 Гость смотрят эту тему.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« : 16-01-2005 20:18 » 

Не подскажет ли кто идею, каким образом ожидать завершение нескольких потоков?
Как я понимаю, аналога wait() в pthread нет, есть только pthread_join(), но она разрешает ожидать завершения только одного, указанного, потока.

Я пока нагородил такую конструкцию: каждому потоку у меня соответствует переменная, которую я перед pthread_create() устанавливаю в 1, и периодически просматриваю их: каждый поток, посредством ф-ии, устанавливаемой через pthread_cleanup_push(), по завершению устанавливает свою переменную в 0.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #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; |
}
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 17-01-2005 15:01 » 

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

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

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

Предложенное решение гарантирует, что поток-родитель разблокируется при завершении произвольного потомка.  Недостаток -- нет возможности получить информацию о том, кто из потомков завершился.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #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
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #5 : 18-01-2005 12:13 » 

RXL, я не силён в программинге под *nix, но может тебе пригодится вот эта книга. Там есть целый раздел по программингу в *nix системах.
Ещё есть вот эта, полностью посвящена программингу в никсах. Обе книги на русском языке.
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 18-01-2005 12:48 » 

MOPO3, спасибо. Только вторая ссылка не работает: The requested URL /test/shelek/linix.rar was not found on this server.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #7 : 18-01-2005 12:54 » 

Sorry Улыбаюсь вот тут нормально лежит Улыбаюсь обшибся я в написании названия файла Ага
« Последнее редактирование: 18-01-2005 13:07 от MOPO3 » Записан

MCP, MCAD, MCTS:Win, MCTS:Web
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 18-01-2005 13:17 » 

RXL,

у меня есть книга под названием "PThreads для начинающих" (PThreads Primer).  Правда, название сильно преуменьшает сложность книги, или автор очень высокого мнения о "начинающих".  Тем не менее, читать можно.  Местами довольно понятно Улыбаюсь

Если нужно, могу открыть через веб, а ты или мороз выложите на сайт шелека.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
MOPO3
Ай да дэдушка! Вах...
Команда клуба

lt
Offline Offline
Пол: Мужской
Холадна аднака!


WWW
« Ответ #9 : 18-01-2005 13:19 » 

npak, я выложить не смогу. Не имею доступа ни к фтп с книгами, ни к админской части сайта Улыбаюсь
Записан

MCP, MCAD, MCTS:Win, MCTS:Web
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 18-01-2005 19:28 » new

npak, спасибо. Судя по оглавлению, то что нужно.

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

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines