У меня есть следующий пример кода (см. Код ниже), который выполняется по потоку:
A: rd-lock
B: wr-lock (waiting)
A: rd-lock (recursive)
A: rd-unlock (recursive)
A: rd-unlock
B: wr-locked (wake after wait)
B: wr-unlock.
По сути, блокировка чтения рекурсивна.Это требуется стандартами POSIX (требует, чтобы блокировки чтения были рекурсивными, но не указаны для блокировок записи).Это работает в Linux, FreeBSD, Solaris, однако не работает в Darwin / Mac OS X.
Пример ниже дает следующий вывод для Linux:
read locking
read locked
write locking
read locking 2
read locked 2
read unlocked 2
read unlocked
write locked
write unlocked 2
В то время как в Darwin он печатает:
read locking
read locked
write locking
read locking 2
И здесь взаимоблокировки (не продолжаются), в основном это не относится к рекурсивной блокировке чтения.
Есть ли что-нибудь, что можно сделать (пометить, определить, связать со специальнымверсия библиотеки) что бы он работал как положено?
Пример кода
#include <pthread.h>
#include <stdio.h>
pthread_rwlock_t lock;
void *thread_r(void *p)
{
printf("read locking\n");
pthread_rwlock_rdlock(&lock);
printf("read locked\n");
usleep(500*1000);
printf("read locking 2\n");
pthread_rwlock_rdlock(&lock);
printf("read locked 2\n");
usleep(500*1000);
pthread_rwlock_unlock(&lock);
printf("read unlocked 2\n");
usleep(500*1000);
pthread_rwlock_unlock(&lock);
printf("read unlocked\n");
}
void *thread_w(void *p)
{
usleep(250*1000);
printf("write locking\n");
pthread_rwlock_wrlock(&lock);
printf("write locked\n");
pthread_rwlock_unlock(&lock);
printf("write unlocked 2\n");
}
int main()
{
pthread_t a,b;
pthread_rwlock_init(&lock,NULL);
pthread_create(&a,NULL,thread_r,0);
pthread_create(&b,NULL,thread_w,0);
pthread_join(a,NULL);
pthread_join(b,NULL);
return 0;
}