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

来源:互联网 发布:qq飞车王国战神数据 编辑:程序博客网 时间:2024/06/07 19:46

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

#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);    //_swap(b,a);//解决方法    return NULL;}int main(){    pthread_t pid1,pid2;    int ret=pthread_create(&pid1,NULL,worker1,NULL);    assert(ret==0);    ret=pthread_create(&pid2,NULL,worker2,NULL);    assert(ret==0);    ret=pthread_join(pid1,NULL);    assert(ret==0);    ret=pthread_join(pid2,NULL);    assert(ret==0);    return 0;}

解决办法是:请求对象的互斥量时先比较对象的地址,始终保持按照地址大小顺序来进行加锁从而保证了顺序加锁。这样的情形在operator=()操作中也可能出现

原创粉丝点击