У меня проблема с мьютексами (pthread_mutex в Linux), когда если поток снова блокирует мьютекс сразу после его разблокировки, другой поток не очень успешно получает блокировку. Я приложил тестовый код, в котором создается один мьютекс, а также два потока, которые в бесконечном цикле блокируют мьютекс, некоторое время спят и снова его разблокируют.
Вывод, который я ожидаю увидеть, это «живые» сообщения от обоих потоков, по одному от каждого (например, 121212121212. Однако я получаю, что один поток получает большинство блокировок (например, 111111222222222111111111 или просто 1111111111111 ...).
Если я добавляю usleep (1) после разблокировки, все работает как положено. Очевидно, когда поток переходит в режим SLEEP, другой поток получает свою блокировку - однако я ожидал этого не так, поскольку другой поток уже вызвал pthread_mutex_lock. Я подозреваю, что это способ, которым это реализовано, в том, что поток actice имеет приоритет, однако это вызывает определенную проблему в этом конкретном тестовом примере. Есть ли способ предотвратить это (кроме добавления намеренно большой задержки или какой-либо сигнализации) или где моя ошибка в понимании?
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
pthread_mutex_t mutex;
void* threadFunction(void *id) {
int count=0;
while(true) {
pthread_mutex_lock(&mutex);
usleep(50*1000);
pthread_mutex_unlock(&mutex);
// usleep(1);
++count;
if (count % 10 == 0) {
printf("Thread %d alive\n", *(int*)id);
count = 0;
}
}
return 0;
}
int main() {
// create one mutex
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutex_init(&mutex, &attr);
// create two threads
pthread_t thread1;
pthread_t thread2;
pthread_attr_t attributes;
pthread_attr_init(&attributes);
int id1 = 1, id2 = 2;
pthread_create(&thread1, &attributes, &threadFunction, &id1);
pthread_create(&thread2, &attributes, &threadFunction, &id2);
pthread_attr_destroy(&attributes);
sleep(1000);
return 0;
}