2013-02-13 2 views
0

Я написал следующее короткое приложение для решения проблемы барьера. Это приложение должно гарантировать, что три идентичные нити, выполняющие один и тот же метод потока, будут «встречаться» в общем разделе кода. Я побежал, и все выглядит нормально. Мой вопрос:барьер для N потоков с полуфорой

1) Правильно ли это?

2) Есть ли предпочтительный и эффективный способ его реализации для N потоков?

вот код:

static sem_t t_1_sem; 

static sem_t t_2_sem; 

static sem_t t_3_sem; 



struct my_thread_info { 
    int num; 
}; 

void *thread(void *vargp) 

{ 

     struct my_thread_info *info = (struct my_thread_info*)vargp; 
     static int counter=0; 
     counter++; 

     if (info->num == 1) { 
       printf("info->num=%d\n", info->num); 
       if (counter<3) 
        sem_wait(&t_1_sem); // down 
       else { 
        sem_post(&t_2_sem); // up 
        sem_post(&t_3_sem); // up     
       } 

     } else 
      if (info->num == 2) { 
       printf("info->num=%d\n", info->num); 
      if (counter<3)    
        sem_wait(&t_2_sem);    
       else { 
        printf("info->num=%d\n", info->num); 
        sem_post(&t_1_sem); 
        sem_post(&t_3_sem); //up    
      } 
      } 
      else 
      if (info->num == 3) { 
       printf("info->num=%d\n", info->num); 
      if (counter<3)    
        sem_wait(&t_3_sem);    
       else { 
        sem_post(&t_1_sem); 
        sem_post(&t_2_sem); //up    
      } 
     } 
     printf("meeting occured!\n"); 

} 

int main() 
{ 
    pthread_t tid0, tid1, tid2; 

    struct my_thread_info info1, info2, info3; 
    info1.num = 1; 

    sem_init(&t_1_sem, 0, 0); 
    sem_init(&t_2_sem, 0, 0); 
    sem_init(&t_3_sem, 0, 0); 

    pthread_create(&tid0, NULL, thread, &info1); 
    info2.num = 2; 

    pthread_create(&tid1, NULL, thread, &info2); 

    info3.num = 3; 
    pthread_create(&tid2, NULL, thread, &info3); 


    pthread_join(tid0, NULL); 
    pthread_join(tid1, NULL); 
    pthread_join(tid2, NULL); 
    pause(); 
    return 0; 

} 

С уважением Кевин

+0

Смотрите также функции pthread_barrier_XXX если вам нужны только барьеры. – nos

ответ

0

Прежде всего вашей counter переменной неохраняемая - и есть возможное условие гонки при выполнении counter++. Использовать мьютекс;

Что касается N потоков - использование массива потоков/семафоров приемлемо для IMO, у меня есть код, который использует этот дизайн, и он работает хорошо.

0

1.Нет неточно. Выполнение таких приращений, как counter++;, приведет к состоянию гонки, и оно не будет увеличивать счетчик должным образом. Вы хотите окружить его критической секцией.

2.

static pthread_mutex_t cs_mutex = PTHREAD_MUTEX_INITIALIZER; 
static sem_t t_sem; 

void *thread(void *vargp) 
{ 
    static int counter=0; 
    pthread_mutex_lock(&cs_mutex); 
    counter++; 
    pthread_mutex_unlock(&cs_mutex); 

    if(counter == NO_THREADS) 
     sem_post(&t_sem); 

    sem_wait(&t_sem); 
    sem_post(&t_sem); 
} 
int main(int argc, char *argv[]){ 

    pthread_t tids[NO_THREADS]; 
    sem_init(&t_sem, 0, 0); 

    for(i=0; i<NO_THREADS; i++){ 
     pthread_create(&tids[i], NULL, thread, NULL); 
    } 

    for(i=0; i<NO_THREADS; i++){ 
     pthread_join(&tids[i], NULL); 
    } 
    pause(); 
    return 0; 
} 
+0

Разве ваш «встречный» доступ в состоянии небезопасен? И как ваш ответ отличается от моего, так или иначе? : P – Dariusz

+0

Я думал, что OP нужно что-то более конкретное ...? 'if (counter == NO_THREADS)' отлично, так как мы не заботимся о положительных значениях семафора. – JosephH

+0

Условие if может никогда не быть выполнено ... – Dariusz

Смежные вопросы