1 qemy_mutex_*
qemu_mutex_init –> pthread_mutex_init、qemu_mutex_destroy –> pthread_mutex_destroy、qemu_mutex_lock –> pthread_mutex_lock(如果锁被占据,则阻塞当前线程)、qemu_mutex_trylock –> pthread_mutex_trylock(不会阻塞当前线程,会立即返回一个锁的状态值)、qemu_mutex_unlock –> pthread_mutex_unlock
1.1 互斥锁属性
互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。
当前(glibc2.2.3,linuxthreads0.9)有四个值可供选择:
* PTHREAD_MUTEX_TIMED_NP,这是缺省值,也就是普通锁。当一个线程加锁以后,其余请求锁的线程将形成一个等待队列,并在解锁后按优先级获得锁。这种锁策略保证了资源分配的公平性。
* PTHREAD_MUTEX_RECURSIVE_NP,嵌套锁,允许同一个线程对同一个锁成功获得多次,并通过多次unlock解锁。如果是不同线程请求,则在加锁线程解锁时重新竞争。
* PTHREAD_MUTEX_ERRORCHECK_NP,检错锁,如果同一个线程请求同一个锁,则返回EDEADLK,否则与PTHREAD_MUTEX_TIMED_NP类型动作相同。这样就保证当不允许多次加锁时不会出现最简单情况下的死锁。
*PTHREAD_MUTEX_ADAPTIVE_NP,适应锁,动作最简单的锁类型,仅等待解锁后重新竞争。
1.2 锁操作
主要包括加锁pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个,不论哪种类型的锁,都不可能被两个不同的线程同时得到,而必须等待解锁。
1.3 实例代码
#include<stdio.h>
#include<pthread.h>
#include<string.h>
typedef struct{
int count;
pthread_mutex_t mutex;
}counter;
void reader(void *arg);
void writer(void *arg);
#define writer_c 10
#define reader_c 20
#define total_c writer_c + reader_c
int main(int argc, char *argv[]){
counter C;
C.count = 0;
srand(time(NULL));
pthread_mutex_init(&(C.mutex), NULL);
pthread_t pt[total_c];
int ret, i;
for(i = 0; i < reader_c; i ++){
ret = pthread_create(&pt[i], NULL, (void *)reader, (void *)&C);
if(ret){
printf("reader %d create error!\n", i + 1);
return -1;
}
}
for(i = 0; i < writer_c; i ++){
ret = pthread_create(&pt[reader_c + i], NULL, (void *)writer, (void *)&C);
if(ret){
printf("writer %d create error!\n", i + 1);
return -1;
}
}
for(i = 0; i < total_c; i ++){
pthread_join(pt[i], NULL);
}
return 0;
}
void reader(void *arg){
counter *c = arg;
while(1){
pthread_mutex_lock(&(c->mutex));
if(c->count > 0){
c->count --;
printf("reader-%lu: (c->count --) = %d\n", pthread_self(), c->count);
}else{
printf("reader-%lu: get nothing!\n", pthread_self());
}
pthread_mutex_unlock(&(c->mutex));
sleep(rand() % 10);
}
}
void writer(void *arg){
counter *c = arg;
while(1){
pthread_mutex_lock(&(c->mutex));
c->count ++;
printf("writer-%lu: (c->count ++)= %d\n", pthread_self(), c->count);
pthread_mutex_unlock(&(c->mutex));
sleep(rand() % 6);
}
}
1.4 缺陷
使用锁机制可以满足线程之间的互斥关系,但是还存在线程同步关系,比如:reader线程和writer线程之间存在同步关系,即:当writer线程产生一个资源(c->count ++)之后,reader线程便可以立即取走该资源(c->count –),因此可以立即唤醒一个被阻塞的reader线程,如果继续等待系统调度一个被阻塞的reader线程或者writer线程的话,便会造成效率低。条件变量是一种通过信号机制和锁机制来解决上述线程同步关系,大致的原理为&#x