#ifndef MUTEX_LOCK1_H
#define MUTEX_LOCK1_H
#include<bits/stdc++.h>
using namespace std;
unordered_map<unsigned long,unsigned long> g_map_tid_waiters_holders;
class Mutex{
private:
pthread_mutex_t _session;
pthread_t _hold_tid;
public:
Mutex(){
_hold_tid=0;
pthread_mutex_init(&_session,nullptr);
}
~Mutex(){
pthread_mutex_destroy(&_session);
}
void lock();
void unlock();
private:
Mutex(const Mutex &);
void operator=(const Mutex&);
bool RecurCheckDeadLock(unsigned long,unsigned long,unsigned long,
unordered_map<unsigned long,unsigned long>&);
};
void Mutex::lock(){
if(_hold_tid!=0&&_hold_tid!=pthread_self()){
cout<<"current thread:"<<pthread_self()<<" wait to get mutex locked by thread:"<<_hold_tid<<endl;
g_map_tid_waiters_holders[pthread_self()]=_hold_tid;
}
auto map_tid_waiters_holders=g_map_tid_waiters_holders;
if(RecurCheckDeadLock(pthread_self(),pthread_self(),_hold_tid,map_tid_waiters_holders)){
cout<<"current thread:"<<pthread_self()<<" deadlock"<<endl;
}
pthread_mutex_lock(&_session);
_hold_tid=pthread_self();
for(auto it=g_map_tid_waiters_holders.begin();it!=g_map_tid_waiters_holders.end();it++){
if(_hold_tid==it->first){
g_map_tid_waiters_holders.erase(it);
break;
}
}
}
void Mutex::unlock(){
pthread_mutex_unlock(&_session);
_hold_tid=0;
}
bool checkdeadlock(unsigned long thread_id,unordered_map<unsigned long ,unsigned long>& map_tid_waiters_holders){
unsigned long key=thread_id;
auto it=map_tid_waiters_holders.begin();
while(key!=it->second){
}
}
bool Mutex::RecurCheckDeadLock(
unsigned long first_key,
unsigned long key,
unsigned long value,
unordered_map<unsigned long ,unsigned long>& map_tid_waiters_holders){
bool ret=false;
for(auto it=map_tid_waiters_holders.begin();it!=map_tid_waiters_holders.end();it++){
if(key==it->first&&value==it->second){
map_tid_waiters_holders.erase(it);
break;
}
}
for(auto it=map_tid_waiters_holders.begin();it!=map_tid_waiters_holders.end();it++){
if(it->first==value){
if(first_key==it->second)
return true;
return RecurCheckDeadLock(first_key,it->first,it->second,map_tid_waiters_holders);
}
}
return ret;
}
#endif
#include"mutex_lock1.h"
#include<bits/stdc++.h>
#include<unistd.h>
Mutex mtx1;
Mutex mtx2;
void* thread1(void*){
mtx1.lock();
cout<<"thread 1 is working"<<endl;
sleep(1);
mtx2.lock();
mtx2.unlock();
mtx1.unlock();
pthread_exit(nullptr);
}
void* thread2(void*){
mtx2.lock();
cout<<"thread 2 is working"<<endl;
sleep(1);
mtx1.lock();
mtx1.unlock();
mtx2.unlock();
pthread_exit(nullptr);
}
int main(){
cout<<getpid()<<endl;
pthread_t tid[2];
if(pthread_create(&tid[0],nullptr,thread1,nullptr)==-1){
perror("pthread create fail");
exit(-1);
}
if(pthread_create(&tid[1],nullptr,thread2,nullptr)==-1){
perror("pthread create fail");
exit(-1);
}
pthread_join(tid[0],nullptr);
pthread_join(tid[1],nullptr);
exit(0);
}