#include
#include
#include
pthread_mutex_t mutex;
void * child1(void *arg)
{
while(1)
{
printf("thread 1 pthread_mutex_lock returns %dn", pthread_mutex_lock(&mutex));
sleep(1);
printf("thread1 pthread_mutex_unLock returns %dn", pthread_mutex_unlock(&mutex));
}
}
void *child2(void *arg)
{
while(1)
{
printf("thread 2 pthread_mutex_lock returns %dn",pthread_mutex_lock(&mutex));
sleep(1);
printf("thread1 pthread_mutex_unLock returns %dn", pthread_mutex_unlock(&mutex));
}
}
int main(void)
{
int tid1,tid2;
printf("hello, condition variable testn");
pthread_mutex_init(&mutex,NULL);
pthread_create(&tid1,NULL,child1,NULL);
pthread_create(&tid2,NULL,child2,NULL);
sleep(100);
pthread_exit(0);
}
互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。当前(glibc2.2.3,linuxthreads0.9)有四个值可供选择:
PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
但事实是并未排队, 总是线程1 在执行, 这到底是怎么回事?
线程1 先启动,并 lock了 mutex, 然后 sleep ,
线程2 的 lock 等待,
线程1 unlock
这时候应该是 线程 2 lock 并执行啊。
为什么总是 线程1 在执行? 难道不是在排队?
|
试了一下,用gdb调试的时候,即使不改成 pthread_mutex_trylock,也是 线程1, 线程2 交互执行。但是直接 a.out ,却总是 线程1 执行。
不过最主要的问题还是这属于“未定义”行为,你不能对这种情况做运行假设。如果要稳定,还是trylock吧。
|
把pthread_mutex_lock改成 pthread_mutex_trylock就可以得到楼主想要的效果了。
man 一下pthread_mutex_lock,就可以知道原因。如果是NORMAL类型的线程锁,当2线程试图对1线程已经锁定的锁再次进行锁定时,会导致线程2死锁。而如果是DEFAULT类型,则是未定义行为。也就是说,也可能导致死锁。
另外,楼主你需要用pthread_join, pthread_mutex_destroy等销毁相关资源。
----man pthread_mutex_lock 节选-------
If the mutex type is PTHREAD_MUTEX_NORMAL, deadlock detection shall not be provided. Attempting to relock the mutex causes deadlock. If a thread attempts to unlock a mutex that it has not locked or a mutex which is unlocked, undefined behavior results.
If the mutex type is PTHREAD_MUTEX_DEFAULT, attempting to recursively lock the mutex results in undefined behavior. Attempting to unlock the mutex if it was not locked by the calling thread results in undefined behavior. Attempting to unlock the mutex if it is not locked results in undefined behavior.
-----改成trylock后的效果----------
[14:51:07@fedora ~/test]$a.out
hello, condition variable test
thread 1 pthread_mutex_lock returns 0
thread 2 pthread_mutex_lock returns 16
thread 1 pthread_mutex_unLock returns 0
thread 1 pthread_mutex_lock returns 0
thread 2 pthread_mutex_unLock returns 0
thread 2 pthread_mutex_lock returns 0
thread 1 pthread_mutex_unLock returns 0
thread 1 pthread_mutex_lock returns 0