#include <stdio.h>
#include <errno.h>
#include <pthread.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
void *func(void *arg)
{
while (1) {
printf("begin\n");
pthread_rwlock_wrlock(&rwlock);
printf("fall through wrlock\n");
pthread_rwlock_wrlock(&rwlock);
printf("fall through wrlock\n");
pthread_rwlock_unlock(&rwlock);
printf("fall through unlock\n");
pthread_rwlock_unlock(&rwlock);
printf("end\n");
}
}
int main()
{
pthread_t thd;
pthread_create(&thd, NULL, func, NULL);
sleep(100);
}
~
我在UBUNTU 10.04上面编写代码并运行, 它只是输出
root @ ubuntu:〜#。/ a.out
begin
fall through wrlock
fall through wrlock
fall through unlock
end
begin
..最后在这里阻止
第一次为什么它不会阻挡
第二个
pthread_rwlock_wrlock(&amp; rwlock)
称为
答案 0 :(得分:8)
如果调用线程在调用时保持读写锁(无论是读还是写锁),结果都是未定义的。
这是the Open Group page on pthread_rwlock_wrlock
。
您正在做的事情是未定义的,至少在该版本的规范中。你很幸运,恶毒的猴子没有从窗户飞过来打死你: - )
在任何情况下,您都应该检查所有pthread函数的返回码。他们可以失败,而你真的不想继续假设你有一个锁,而事实上你没有,因为那种否定了它的用处锁。
与上述相关的同一页面说明:
如果出现以下情况,
pthread_rwlock_wrlock()
和pthread_rwlock_trywrlock()
功能可能会失败:
[EINVAL]
- rwlock指定的值不引用初始化的读写锁对象[EDEADLK]
- 当前线程已经拥有用于写入或读取的读写锁。
我会检查你是否真的找回了EDEADLK
错误代码。即使在the latest editions of POSIX threads中也存在此错误代码,正如Nemo在评论中指出的那样,“未定义”的措辞已被删除。
我将此视为实际死锁,即线程完全锁定。 EDEADLK
错误代码部分还指出“pthread_rwlock_wrlock()
函数可能失败,如果......”(再次,我的粗体)。
这些陈述中都有狡猾的单词“may”,因此在任何特定情况下仍然没有明确定义。它可能(没有双关语意)是因为某些实现的表现不同(事先并不总是很容易检测到死锁情况),但这是我的纯粹推测。
底线,除非你知道你有某种递归锁(你可以重新锁定而不受惩罚),不要这样做。