当多个线程中为了保护多个共享资源而使用了多个互斥锁,如果多个互斥锁使用不当,就可能造成,多个线程一直等待对方的锁释放,这就是死锁现象。
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<time.h>
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;
void* thread1(void* arg) {
printf("子线程获取mtx1中。。。。\n");
pthread_mutex_lock(&mtx1);
printf("子线程获取mtx1成功\n");
sleep(3);
printf("子线程获取mtx2中。。。。\n");
pthread_mutex_lock(&mtx2);
printf("子线程获取mtx2成功\n");
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
}
int main(int argc, char* argv[])
{
//初始化一个互斥量
pthread_mutex_init(&mtx1, NULL);
pthread_mutex_init(&mtx2, NULL);
pthread_t tids;
pthread_create(&tids, NULL, thread1, NULL);
printf("主线程获取mtx2中。。。。\n");
pthread_mutex_lock(&mtx2);
printf("主线程获取mtx2成功\n");
sleep(3);
printf("主线程获取mtx1中。。。。\n");
pthread_mutex_lock(&mtx1);
printf("主线程获取mtx1成功\n");
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
pthread_mutex_destroy(&mtx1);
pthread_mutex_destroy(&mtx2);
return 0;
}
死锁了
死锁产生的四个必要条件:
●互斥条件:资源只能同时被一个线程占用
●持有并等待条件:线程1已经持有资源A,可以申请持有资源B,如果资源B已经被线程2持有,这时线程1持有资源并等待资源B
●不可剥夺条件:一个线程持有资源,只能自己释放后其他线程才能使用。其他线程不能强制收回该资源
●环路等待条件:多个线程互相等待资源,形成一个环形等待链
避免死锁:破坏其中一个必要条件就可以避免死锁
常用的方法如下:
●锁的粒度控制:破坏请求与保持条件,尽可能减少持有锁的时间,降低发生死锁的可能性
●资源有序分配:破坏环路等待条件,规定线程使用资源的顺序,按规定顺序给资源加锁
●重试机制:破坏不可剥夺条件,如果尝试获取资源失败,放弃已持有的资源后重试
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<time.h>
//资源有序分配,破坏环路等待条件,规定线程使用资源的顺序,按规定顺序给资源加锁
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;
void* thread1(void* arg) {
printf("子线程获取mtx1中。。。。\n");
pthread_mutex_lock(&mtx1);
printf("子线程获取mtx1成功\n");
sleep(3);
printf("子线程获取mtx2中。。。。\n");
pthread_mutex_lock(&mtx2);
printf("子线程获取mtx2成功\n");
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
}
int main(int argc, char* argv[])
{
//初始化一个互斥量
pthread_mutex_init(&mtx1, NULL);
pthread_mutex_init(&mtx2, NULL);
pthread_t tids;
pthread_create(&tids, NULL, thread1, NULL);
printf("主线程获取mtx1中。。。。\n");
pthread_mutex_lock(&mtx1);
printf("主线程获取mtx1成功\n");
sleep(3);
printf("主线程获取mtx2中。。。。\n");
pthread_mutex_lock(&mtx2);
printf("主线程获取mtx2成功\n");
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
sleep(10);
pthread_mutex_destroy(&mtx1);
pthread_mutex_destroy(&mtx2);
return 0;
}
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<fcntl.h>
#include<errno.h>
#include<stdlib.h>
#include<time.h>
//重试机制:破坏不可剥夺条件,如果尝试获取资源失败,放弃已持有的资源后重试
pthread_mutex_t mtx1;
pthread_mutex_t mtx2;
void* thread1(void* arg) {
printf("子线程获取mtx1中。。。。\n");
while(1) {
pthread_mutex_lock(&mtx1);
printf("子线程获取mtx1成功\n");
sleep(3);
printf("子线程获取mtx2中。。。。\n");
int ret = pthread_mutex_trylock(&mtx2);
if(ret != 0 && ret == EBUSY) {
pthread_mutex_unlock(&mtx1);
printf("子线程释放mtx1\n");
sleep(1);
continue;
}
printf("子线程获取mtx2成功\n");
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
break;
}
}
int main(int argc, char* argv[])
{
//初始化一个互斥量
pthread_mutex_init(&mtx1, NULL);
pthread_mutex_init(&mtx2, NULL);
pthread_t tids;
pthread_create(&tids, NULL, thread1, NULL);
while(1) {
printf("主线程获取mtx2中。。。。\n");
pthread_mutex_lock(&mtx2);
printf("主线程获取mtx2成功\n");
sleep(3);
printf("主线程获取mtx1中。。。。\n");
int ret = pthread_mutex_trylock(&mtx1);
if(ret != 0 && ret == EBUSY) {
pthread_mutex_unlock(&mtx2);
printf("主线程释放mtx2\n");
sleep(1);
continue;
}
printf("主线程获取mtx1成功\n");
pthread_mutex_unlock(&mtx2);
pthread_mutex_unlock(&mtx1);
break;
}
sleep(10);
pthread_mutex_destroy(&mtx1);
pthread_mutex_destroy(&mtx2);
return 0;
}