我有以下示例代码(请参阅下面的代码),它由线程执行:
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.
基本上,read-lock是递归的。它是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
在达尔文上打印时:
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;
}
答案 0 :(得分:1)
只有rdlock()支持递归锁定:
http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_rwlock_rdlock.html
根据Unix规范,如果线程已经拥有读或写锁,则调用wrlock()的行为是不确定的:
http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_rwlock_trywrlock.html
当您使用OS X时,请查看NSRecursiveLock:
答案 1 :(得分:0)
是的,锁是rwlocks上的读锁确实是递归的,直到某一点。但是POSIX docs for pthread_rwlock_rdlock
,SUSv2中有一条线,因为这是Apple支持的:
如果编写器没有锁定并且锁上没有写入器被阻塞,则调用线程获取读锁定。当编写器没有持有锁并且有编写者等待锁时,调用线程是否获取锁是未指定的。
没有任何关于让现有读锁的线程重新锁定以进行读取的内容。只是如果写入器被阻塞,读取锁定请求将被阻塞(实现通常优先考虑写入锁定以避免写入者饥饿)。
Apple's own online docs也支持这一点:
pthread_rwlock_rdlock()函数获取rwlock的读锁定,前提是当前没有写入rwlock进行写入,并且当前没有锁定写入器线程。
后来:
为了防止作家饥饿,作家比读者更受青睐。
再次。没有提到在写入锁定在队列中时允许递归读锁定。