5.线程与并发同步-linux学习笔记-死锁

死锁
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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值