一个函数锁住相同类型的多个对象造成的死锁

在编程中,一个类型内的互斥量被用于锁定多个实例。由于在多线程环境中未正确处理加锁顺序,导致了死锁现象的发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个类型中有个互斥量变量,一个函数锁住这个类型的多个对象,由于编码不注意加锁顺序在多线程环境下造成了死锁。

#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<assert.h>
using namespace std;
class test{//持有一个互斥锁
    public:
        test(){
            pthread_mutex_init(&mutex,NULL);
        }
        void lock(){
            pthread_mutex_lock(&mutex);
        }
        void unlock(){
            pthread_mutex_unlock(&mutex);
        }
    private:
        pthread_mutex_t mutex;
};
test a,b;

void swap(test& a,test& b){//
    a.lock();//先锁住a
    sleep(2);//睡眠是为了另一个线程先锁住b,造成两个线程死锁
    b.lock();//再锁b
    b.unlock();
    a.unlock();
}
void _swap(test& a,test& b){
    if(&a<&b){
        swap(a,b);
    }
    else{
        swap(b,a);
    }
}
void* worker1(void* arg){//线程1先锁a再锁b
    swap(a,b);
    //_swap(a,b);//解决方法是请求锁的时候先比较对象地址
    return NULL;
}
void* worker2(void* arg){//线程2先锁b再锁a,因此两个线程死锁
    swap(b,a);
    //_swa
### 在多线程环境下使用互斥锁(IMutex)确保线程安全 在多线程环境中,当多个线程调用同一函数并尝试访问共享资源时,如果不采取措施,可能会引发竞态条件或数据不一致等问题。为此,可以利用互斥锁(IMutex)来实现线程同步,从而保障线程安全。 #### 1. 初始化互斥锁 在使用互斥锁之前,必须先对其进行初始化。以下是两种常见的初始化方式: - **静态初始化**:适用于简单场景下的互斥锁定义。 ```c++ pthread_mutex_t myMutex = PTHREAD_MUTEX_INITIALIZER; ``` - **动态初始化**:提供更灵活的配置选项。 ```c++ pthread_mutex_t myMutex; pthread_mutex_init(&myMutex, NULL); ``` 这两种方法都可以成功创建一个互斥锁实例[^2]。 #### 2. 锁定与解锁过程 为了确保线程间的安全性,在访问共享资源前后需分别执行锁定和解锁操作。具体流程如下所示: - 调用 `pthread_mutex_lock` 函数对指定的互斥锁加锁。一旦某个线程成功获取到锁之后,其他试图获取相同锁的线程将会阻塞直到当前持有者释放为止。 - 访问完毕后应尽快调用 `pthread_mutex_unlock` 来解除对该资源的独占使用权以便让处于等待状态下的其它进程得以继续运行下去。 ```c++ void shared_resource_access(pthread_mutex_t* mutex) { pthread_mutex_lock(mutex); // 尝试获得互斥锁 // 关键区域 - 修改共享资源的具体业务逻辑在此处编写 printf("Thread %lu accessing shared resource\n", (unsigned long)pthread_self()); pthread_mutex_unlock(mutex); // 主动释放互斥锁 } ``` 以上代码片段展示了如何在线程函数中合理运用互斥锁保护共享资源不受并发影响的同时也体现了良好的编码习惯——始终记得及时解铃还须系铃人原则即谁申请就由谁负责清理善后工作以免造成不必要的麻烦如死锁等情况发生[^3]。 另外值得注意的一点是在实际开发过程中我们往往倾向于借助RAII技术来自动生成管理对象生命期内所需的各类资源分配销毁动作以简化手动干预带来的风险降低错误发生的概率例如C++标准库提供了std::lock_guard辅助类可以帮助自动完成上述繁琐而又容易遗忘的重要环节: ```cpp #include <mutex> std::mutex mtx; void thread_safe_function() { std::lock_guard<std::mutex> lock(mtx); // 构造时自动上锁,析构时自动解锁 // 这里是对共享资源进行操作的部分 } ``` 此版本不仅更加简洁明了而且有效规避掉了因忘记显式调用unlock而导致长期占用公共资源进而引起系统整体性能下降甚至崩溃的可能性大大提升了软件质量水平[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值