死锁
1. 线程试图对同一个互斥量A加锁两次。
2. 线程1拥有A锁,请求获得B锁;线程2拥有B锁,请求获得A锁
【作业】:编写程序,实现上述两种死锁现象。
1. 线程试图对同一个互斥量A加锁两次。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#define MAX 10
// 全局变量
int number;
//创建一把互斥锁
pthread_mutex_t mutex;
// 线程处理函数
void* funcA_num(void* arg)
{
for(int i=0; i<MAX; ++i)
{
//访问全局变量之前加锁
//如果mutex被锁上了,代码阻塞在当前位置
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&mutex);//重复加锁
int cur = number;
cur++;
number = cur;
printf("Thread A, id = %lu, number = %d\n", pthread_self(), number);
//解锁
pthread_mutex_unlock(&mutex);
usleep(10);
}
return NULL;
}
int main(){
pthread_t p1;
//初始化互斥锁
pthread_mutex_init(&mutex,NULL);
// 创建两个子线程
pthread_create(&p1, NULL, funcA_num, NULL);
// 阻塞,资源回收
pthread_join(p1, NULL);
//释放互斥锁资源
pthread_mutex_destroy(&mutex);
return 0;
}
2. 线程1拥有A锁,请求获得B锁;线程2拥有B锁,请求获得A锁
线程A已经拥有A锁,线程B已经拥有B锁,
线程A请求获得B锁,线程B请求获得A锁
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#define MAX 10
// 全局变量
int number1=0,number2=0;
//创建一把互斥锁
pthread_mutex_t mutexA,mutexB;
// 线程处理函数
void* funcA_num(void* arg)
{
pthread_mutex_lock(&mutexA);
printf("Thread A get mutexA\n");
int cur = number1;
cur++;
number1 = cur;
sleep(5);
printf("Thread A want get mutexB\n");
pthread_mutex_lock(&mutexB);
printf("Thread A, id = %lu, number = %d\n", pthread_self(), number1);
//解锁
pthread_mutex_unlock(&mutexA);
usleep(10);
return NULL;
}
// 线程处理函数
void* funcB_num(void* arg)
{
pthread_mutex_lock(&mutexB);
printf("Thread B get mutexB\n");
int cur = number2;
cur++;
number2 = cur;
sleep(5);
printf("Thread B want get mutexA\n");
pthread_mutex_lock(&mutexA);
printf("Thread B, id = %lu, number = %d\n", pthread_self(), number2);
//解锁
pthread_mutex_unlock(&mutexB);
usleep(10);
return NULL;
}
int main(){
pthread_t p1, p2,p3;
//初始化互斥锁
pthread_mutex_init(&mutexA,NULL);
pthread_mutex_init(&mutexB,NULL);
// 创建两个子线程
pthread_create(&p1, NULL, funcA_num, NULL);
pthread_create(&p2, NULL, funcB_num, NULL);
// 阻塞,资源回收
pthread_join(p1, NULL);
pthread_join(p2, NULL);
//释放互斥锁资源
pthread_mutex_destroy(&mutexA);
pthread_mutex_destroy(&mutexB);
return 0;
}
输入命令 gcc sisuo2.c -pthread
接着 ./a.out
输出为
Thread B get mutexB
Thread A get mutexA
Thread B want get mutexA
Thread A want get mutexB
这里造成了死锁现象
避免死锁,使用pthread_mutex_trylock
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#define MAX 10
// 全局变量
int number1=0,number2=0;
//创建一把互斥锁
pthread_mutex_t mutexA,mutexB;
// 线程处理函数
void* funcA_num(void* arg)
{
pthread_mutex_lock(&mutexA);
printf("Thread A get mutexA\n");
int cur = number1;
cur++;
number1 = cur;
printf("Thread A, id = %lu, number1 = %d\n", pthread_self(), number1);
sleep(rand()%5);//;rand()%5+1
printf("Thread A want get mutexB\n");
int r = pthread_mutex_trylock(&mutexB);
//fail
if(r){
printf("Thread A get mutexB failed,pthread_mutex_unlock(&mutexA);\n");
pthread_mutex_unlock(&mutexA);
}
//get mutexB
else{
//
printf("Thread A get mutexB successfully\n");
printf("Thread A, id = %lu, number2 = %d\n", pthread_self(), ++number2);
sleep(rand()%2+1);
pthread_mutex_unlock(&mutexB);
pthread_mutex_unlock(&mutexA);
}
return NULL;
}
// 线程处理函数
void* funcB_num(void* arg)
{
pthread_mutex_lock(&mutexB);
printf("Thread B get mutexB\n");
int cur = number2;
cur++;
number2 = cur;
printf("Thread B, id = %lu, number2 = %d\n", pthread_self(), number2);
sleep(rand()%5);
printf("Thread B want get mutexA\n");
int r = pthread_mutex_trylock(&mutexA);
//fail
if(r){
printf("Thread B get mutexA failed,pthread_mutex_unlock(&mutexB);\n");
pthread_mutex_unlock(&mutexB);
}
//get mutexB
else{
//
printf("Thread B get mutexA successfully\n");
printf("Thread B, id = %lu, number1 = %d\n", pthread_self(), ++number1);
sleep(rand()%2+1);
pthread_mutex_unlock(&mutexA);
pthread_mutex_unlock(&mutexB);
}
return NULL;
}
int main(){
pthread_t p1, p2,p3;
//初始化互斥锁
pthread_mutex_init(&mutexA,NULL);
pthread_mutex_init(&mutexB,NULL);
// 创建两个子线程
pthread_create(&p1, NULL, funcA_num, NULL);
pthread_create(&p2, NULL, funcB_num, NULL);
// 阻塞,资源回收
pthread_join(p1, NULL);
pthread_join(p2, NULL);
//释放互斥锁资源
pthread_mutex_destroy(&mutexA);
pthread_mutex_destroy(&mutexB);
return 0;
}
编译输出:
Thread B get mutexB
Thread B, id = 140313202267904, number2 = 1
Thread A get mutexA
Thread A, id = 140313210660608, number1 = 1
Thread A want get mutexB
Thread A get mutexB failed,pthread_mutex_unlock(&mutexA);
Thread B want get mutexA
Thread B get mutexA successfully
Thread B, id = 140313202267904, number1 = 2