поведение потоков на нескольких блокировках одного мьютекса - PullRequest
1 голос
/ 06 июня 2011

Если я заблокирую один и тот же мьютекс в двух разных местах в моей функции, и произойдет переключение контекста, когда один поток находится в одном из них, а второй поток перейдет к другому, будет ли он заблокирован?

Я постараюсь привести простой пример того, что я имею в виду, может быть, это будет понятнее.Скажем, у меня есть следующий код в файле test.c

int globalVar = 0;    

void testMutex(pthread_mutex_t myMutex) {
    pthread_mutex_lock(&myMutex);
    globalVar++;
    pthread_mutex_unlock(&myMutex);

    printf("%s \n", "Doing some other stuff here");

    pthread_mutex_lock(&myMutex);
    globalVar--;
    pthread_mutex_unlock(&myMutex);
}

и в другом файле main.c, у меня есть функция main, которая создает два потока, thread1 и thread2, оба работаютtestMutex функция.thread1 выполняется первым, а во второй части функции (часть -, после printf), перед тем как мьютекс разблокирован, thread2 запускается с начала функции.thread2 сможет выполнить globalVar++ или останется заблокированным, ожидая разблокировки мьютекса?

Заранее спасибо!

Ответы [ 5 ]

4 голосов
/ 06 июня 2011

Прежде всего, вы не должны передавать pthread_mutex_t по значению:

void testMutex(pthread_mutex_t myMutex)

Сделай это pthread_mutex_t*. Даже если ваш код может работать на вас (в чем я сомневаюсь), он не переносим, ​​поскольку типы pthreads должны быть непрозрачными.

Это обсуждается в соответствующем FAQ . Среди прочего, он намекает на возможность того, что использование pthread_mutex_t приведет к копированию мьютекса , создаваемого при каждом вызове testMutex (с функцией, блокирующей копию вместо оригинала мьютекс).

Как только вы исправите это, будет действовать следующее:

Поскольку два потока используют один и тот же мьютекс, второй поток с блоком на любом из двух pthread_mutex_lock требует, чтобы первый поток находился внутри одного из двух разделов pthread_mutex_lock - pthread_mutex_unlock. Обратное также верно (первый поток блокируется до тех пор, пока второй поток имеет мьютекс).

Другими словами, пока один поток имеет блокировку мьютекса, никакой другой поток не может заблокировать тот же мьютекс.

4 голосов
/ 06 июня 2011

Краткий ответ "да".

Документация pthread_mutex_lock довольно ясно дает понять:

Объект мьютекса, на который ссылается мьютекс, должен быть заблокирован вызовом pthread_mutex_lock (). Если мьютекс уже заблокирован, вызывающий поток должен блокироваться, пока мьютекс не станет доступным. Эта операция должна вернуться с объектом мьютекса, на который ссылается мьютекс, в заблокированном состоянии с вызывающим потоком в качестве его владельца.

Другими словами, по возвращении из pthread_mutex_lock мьютекс «принадлежит» потоку. Система гарантирует, что не более одного потока может «владеть» одним мьютексом в любое время.

1 голос
/ 06 июня 2011

thread2 будет блокироваться в функции pthread_mutex_lock (), пока thread1 не разблокирует мьютекс.

Если нет, то какова цель мьютекса на первом месте?

0 голосов
/ 06 июня 2011

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

0 голосов
/ 06 июня 2011

thread2 останется заблокированным и не сможет увеличивать globalVarr ++, пока thread1 не освободит мьютекс.

...