winston 发表于 2011-12-20 10:09:47

多线程的那点儿事(之避免死锁)

【 声明:版权所有,欢迎转载,请勿用于商业用途。联系信箱:feixiaoxing @163.com】


预防死锁的注意事项:
(1)在编写多线程程序之前,首先编写正确的程序,然后再移植到多线程
(2)时刻检查自己写的程序有没有在跳出时忘记释放锁
(3)如果自己的模块可能重复使用一个锁,建议使用嵌套锁
(4)对于某些锁代码,不要临时重新编写,建议使用库里面的锁,或者自己曾经编写的锁
(5)如果某项业务需要获取多个锁,必须保证锁的按某种顺序获取,否则必定死锁(6)编写简单的测试用例,验证有没有死锁

(7)编写验证死锁的程序,从源头避免死锁

    首先,定义基本的数据结构和宏,
view plain

[*]typedef
struct _LOCK_INFO[*]{[*]    char lockName;[*]    HANDLE hLock;[*]}LOCK_INFO:[*]
[*]typedef
struct _THREAD_LOCK[*]{[*]    int threadId;[*]    LOCK_INFO* pLockInfo;[*]}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))
    然后,改写锁的申请函数,

view plain

[*]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);[*]}
    最后,需要改写锁的释放函数。

view plain

[*]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);[*]}[*]
页: [1]
查看完整版本: 多线程的那点儿事(之避免死锁)