死锁
两个线程试图同时占用两个资源,并按不同的次序锁定相应的共享资源
解决方式
- 按相同的次序锁定相应的共享资源
- 使用函数pthread_mutex_trylock(),它是函数pthread_mutex_lock()的非阻塞函数
死锁案例
线程A先对资源a上锁,然后睡眠,线程B也对资源b上锁,然后睡眠,线程a睡眠结束后继续对资源b上锁,这时资源b已经被线程b上锁了,线程a被阻塞,同时线程b也继续对资源a上锁,但是资源a已经被线程a上锁了,线程b也被阻塞,出现死锁现象
#include <pthread.h>
#include <string.h>
#include <errno.h>
typedef struct
{
int value;
pthread_mutex_t mutex;
}ResourceA;
typedef struct
{
int value;
pthread_mutex_t mutex;
}ResourceB;
typedef struct
{
ResourceA *ra;
ResourceB *rb;
}Storage;
void* a_fun(void *arg)
{
Storage *s = (Storage *)arg;
//对ResourceA加锁
pthread_mutex_lock(&s->ra->mutex);
sleep(1);
printf("0x%lx is waiting for ResouceB...\n",pthread_self());
//对ResourceB加锁
pthread_mutex_lock(&s->rb->mutex);
printf("ResourceA value is:%d\n",&s->ra->value);
printf("ResourceB value is:%d\n",&s->rb->value);
pthread_mutex_unlock(&s->ra->mutex);
pthread_mutex_unlock(&s->rb->mutex);
}
void* b_fun(void *arg)
{
Storage *s = (Storage *)arg;
//对ResourceB加锁
pthread_mutex_lock(&s->rb->mutex);
sleep(1);
printf("0x%lx is waiting for ResouceA...\n",pthread_self());
//对ResourceA加锁
pthread_mutex_lock(&s->ra->mutex);
printf("ResourceA value is:%d\n",&s->ra->value);
printf("ResourceB value is:%d\n",&s->rb->value);
pthread_mutex_unlock(&s->rb->mutex);
pthread_mutex_unlock(&s->ra->mutex);
}
int main(void)
{
ResourceA ra;
ResourceB rb;
ra.value = 100;
rb.value = 200;
pthread_mutex_init(&ra.mutex,NULL);
pthread_mutex_init(&rb.mutex,NULL);
Storage s = {&ra,&rb};
pthread_t thread_a,thread_b;
pthread_create(&thread_a,NULL,a_fun,(void *)s);
pthread_create(&thread_b,NULL,b_fun,(void *)s);
pthread_join(thread_a,NULL);
pthread_join(thread_b,NULL);
pthread_mutex_destroy(&ra.mutex);
pthread_mutex_destroy(&rb.mutex);
return 0;
}
改进(利用方法1):
只对线程b进行改进
void* b_fun(void *arg)
{
/*
Storage *s = (Storage *)arg;
//对ResourceB加锁
pthread_mutex_lock(&s->rb->mutex);
sleep(1);
printf("0x%lx is waiting for ResouceA...\n",pthread_self());
//对ResourceA加锁
pthread_mutex_lock(&s->ra->mutex);
printf("ResourceA value is:%d\n",&s->ra->value);
printf("ResourceB value is:%d\n",&s->rb->value);
pthread_mutex_unlock(&s->rb->mutex);
pthread_mutex_unlock(&s->ra->mutex);
*/
Storage *s = (Storage *)arg;
//对ResourceA加锁
pthread_mutex_lock(&s->ra->mutex);
sleep(1);
printf("0x%lx is waiting for ResouceB...\n",pthread_self());
//对ResourceB加锁
pthread_mutex_lock(&s->rb->mutex);
printf("ResourceA value is:%d\n",&s->ra->value);
printf("ResourceB value is:%d\n",&s->rb->value);
pthread_mutex_unlock(&s->ra->mutex);
pthread_mutex_unlock(&s->rb->mutex);
}