Разница между блокировкой мьютекса и pthread_join - PullRequest
5 голосов
/ 19 мая 2011

Какая разница между этими двумя?

Разве они не одинаковы в том смысле, что они оба ждут завершения потока, прежде чем выполнять другой поток?

Я пытаюсь понять следующий код

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *functionC();
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int  counter = 0;

main()
{
    int rc1, rc2;
    pthread_t thread1, thread2;

 /*Create independent threads each of which will execute functionC */

     if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
   {
      printf("Thread creation failed: %d\n", rc1);
   }

   if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) )
   {
      printf("Thread creation failed: %d\n", rc2);
   }

   /* Wait till threads are complete before main continues. Unless we  */
   /* wait we run the risk of executing an exit which will terminate   */
   /* the process and all threads before the threads have completed.   */

   pthread_join( thread1, NULL);
   pthread_join( thread2, NULL);

   exit(0);
}    
void *functionC()
{
   pthread_mutex_lock( &mutex1 );
   counter++;
   printf("Counter value: %d\n",counter);
   pthread_mutex_unlock( &mutex1 );
}

Спасибо.

Ответы [ 2 ]

10 голосов
/ 19 мая 2011

На самом деле это не одно и то же.

Мьютекс (семафор взаимного исключения) - это средство, ограничивающее использование ресурса одним потоком за раз (причем оба потока, очевидно, могут работать),Когда поток успешно возвращается из вызова pthread_mutex_lock, он гарантированно является единственным потоком, удерживающим эту блокировку.Любой поток, который пытается заблокировать этот мьютекс после этой точки, как правило, должен ждать, пока поток-владелец не разблокирует его.

Другими словами, поток с блокировкой является единственным потоком, способным манипулировать защищенным этим ресурсом.блокировка (при условии, конечно, что другие потоки не касаются ресурса без предварительного получения блокировки - вы должны играть по правилам).

A pthread_join, с другой стороны, разрешает потокждать, пока другой поток не выйдет на . Это часто используется в основном потоке, чтобы дождаться выхода всех дочерних потоков (есть другие варианты использования, это просто типичное).Успешный возврат из pthread_join означает, что другой поток больше не работает.

В показанном вами коде два потока работают одновременно, и приращение counter и вызов printfзащищены mutex1.Вызовы pthread_join в конце main заставят главный поток ждать, пока два дочерних потока не завершат работу, прежде чем продолжить.

В качестве отступа, вы должны проверить возвращаемые значения с pthread_mutex_lock, поскольку он может потерпеть неудачу.Вы не хотите идти дальше и модифицировать защищенный ресурс в этом случае, поскольку может произойти повреждение.То же самое для pthread_join.

И для более комплексного теста лучше подойдет следующая функция:

void *functionC() {
    int i;
    for (i = 1000; i > 0; i--) {
        pthread_mutex_lock (&mutex1);
        counter++;
        printf ("Counter value: %d\n", counter);
        pthread_mutex_unlock (&mutex1);
    }
}

, так как с большей вероятностью потоки будут выполняться рядом друг с другом,Без цикла есть большая вероятность, что один поток выйдет еще до того, как начнется второй.

3 голосов
/ 19 мая 2011

pthread_join() ожидает завершения потока. Mutex_lock получает контроль над семафором, который препятствует одновременному доступу взаимодействующих потоков к защищенному ресурсу.

...