C ++ multi-threaded - Deadlock prevention

Note deadlock prevention:
(1) Before writing a multithreaded program, first write correct programs and then transplanted to a multi-threaded
(2) the time to write their own inspection procedures have not forgotten when out of the lock is released
(3) if own modules may reuse a lock, we recommend using a nested lock
(4) for some lock the code, do not re-write temporary, it is recommended to use the library inside the lock, or locked themselves had written
(5) If a business needs to obtain multiple locks, the lock must be guaranteed access to some order, otherwise surely deadlock
(6) write a simple test to verify there is no deadlock
(7) programming verification deadlock, from the source to avoid deadlock

First, define the basic data structures and macros,

typedef struct _LOCK_INFO  
{  
    char lockName[32];  
    HANDLE hLock;  
}LOCK_INFO:  
  
typedef struct _THREAD_LOCK  
{  
    int threadId;  
    LOCK_INFO* pLockInfo[32];  
}THREAD_LOCK;  
  
#define CRITICAL_SECTION_TYPE 1  
#define MUTEX_LOCK_TYPE       2  
#define SEMAPHORE_LOCK_TYPE   3  
#define NORMAL_LOCK_TYPE      4  
  
#define WaitForSingleObject(a, b) \  
        WaitForSingleObject_stub((void*)a, NORMAL_LOCK_TYPE)  
  
#define EnterCriticalSection(a) \  
        WaitForSingleObject_stub((void*)a, CRITICAL_SECTION_TYPE)  
  
#define ReleaseMutex(a) \  
        ReleaseLock_stub((void*)a, MUTEX_LOCK_TYPE))  
  
#define ReleaseSemaphore(a, b, c) \  
        ReleaseLock_stub((void*)a, SEMAPHORE_LOCK_TYPE))  
  
#define LeaveCriticalSection(a) \  
        ReleaseLock_stub((void*)a, CRITICAL_SECTION_TYPE))  

Then, rewrite the application lock function,

void WaitForSingleObject_stub(void* hLock, int type)  
{  
    /* step 1 */  
    WaitForSingleObject(hDbgLock);  
    /* check if lock loops arounds threads */  
    ReleaseMutex(hDbgLock);  
  
    /* step 2 */  
    if(NORMAL_LOCK_TYPE == type)  
        WaitForSingleObject((HANDLE)hLock, INFINITE);  
    else if(CRITICAL_SECTION_TYPE == type)  
        EnterCriticalSection((LPCRITICAL_SECTION)hLock);  
    else  
        assert(0);  
  
    /* step 3 */  
    WaitForSingleObject(hDbgLock);  
    /* add lock to specified threadid list */  
    ReleaseMutex(hDbgLock);  
}  

Finally, the need to rewrite the function to release the lock.

void ReleaseLock_stub(void* hLock, int type)  
{  
    /* step 1 */  
    WaitForSingleObject(hDbgLock);  
    /* remove lock from specified threadid list */  
    ReleaseMutex(hDbgLock);  
  
    /* step 2 */  
    if(MUTEX_LOCK_TYPE))== type)  
        ReleaseMutex(HANDLE)hLock);  
    else if(SEMAPHORE_LOCK_TYPE == type)  
        ReleaseSemaphore((HANDLE)hLock, 1, NULL);  
    else if(CRITICAL_SECTION_TYPE == type)  
        LeaveCriticalSection((LPCRITICAL_SECTION)hLock);  
    assert(0);  
}  
Released 1024 original articles · won praise 810 · views 20000 +

Guess you like

Origin blog.csdn.net/weixin_42528266/article/details/103913343