1つの関数が同じタイプの複数のオブジェクトをロックすることによるデッドロック

1415 ワード

1つのタイプには反発量変数があり、1つの関数がこのタイプの複数のオブジェクトをロックし、符号化がロック順序に注意しないため、マルチスレッド環境でデッドロックが発生します.
#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=()操作でも発生する可能性があります.