C++死锁解决心得-1

上一篇 / 下一篇  2012-08-10 10:21:36 / 个人分类:C++

b(?'\Mbo0  一、概述

b0R+W4z2?H051Testing软件测试网$^dJ)CIJ

  C++多线程开发中,容易出现死锁导致程序挂起的现象。

w nVro"Kzw5E*{ \{0

ME*s]7t Zj??0  解决步骤分为三步:51Testing软件测试网@9G;v1L B.f?i

51Testing软件测试网~/Y{4e.f'x

  1、检测死锁线程。51Testing软件测试网 m,N(}-Pu i"w

51Testing软件测试网/F(i4qe0r rZu

  2、打印线程信息。51Testing软件测试网-t d$V"w4e h B1rJ_.?8r

51Testing软件测试网6K~ukD1P

  3、修改死锁程序。51Testing软件测试网P:_1G:o.sJ

s^#X3S;n$G/V0  二、程序示例51Testing软件测试网A2x]7c6YJ'I

1Uc am w#ub0  VS2005创建支持MFC的win32控制台程序。

_I'N(T#e0lE y0

,j.?tC5jV0B1Iw0  代码见示例代码DeadLockTest.cpp。

&O!V#~#c]/W4]051Testing软件测试网6gf%ijUPtSPe

9RF q'xu'R0
51Testing软件测试网,Dbl-?f.q

// DeadLockTest.cpp : Defines the entry point for the console application.51Testing软件测试网5l }6|S)M5Gdhg8Bf
//
51Testing软件测试网d^0Won/GgUVl&J

51Testing软件测试网M[ {'r{)E D*r

#include "stdafx.h"51Testing软件测试网|K o#x!a
#include "DeadLockTest.h"

*fD-E~8sH2A ~S051Testing软件测试网jc#z,|7H%MY

#ifdef _DEBUG
T l_t s@mY&CE"w0#define new DEBUG_NEW
l2N`b xX0#endif

VZ6O;iE6V@x-s0

)UJ(_2P$\!U#L051Testing软件测试网'V2Yg{\S#d d
// The one and only application object

b)t`1B9y zj0

/[/wOc(F.OS.l0CWinApp theApp;

kX2K`(M4vl%er051Testing软件测试网 D%Z#E*D)av*^$_

using namespace std;

*\0Qk"?F]Is051Testing软件测试网 VN"|{f)}Xnk

CRITICAL_SECTION cs1;51Testing软件测试网 Ef5EK)p7L&x)~m
CRITICAL_SECTION cs2;51Testing软件测试网:o9{'Rln)b4s/A*A
CRITICAL_SECTION csprint;

&{c T,n*cT*U+b051Testing软件测试网zy[m,w5?

//初始化关键代码段51Testing软件测试网J:s8X%f9u8E'J
void InitMyCriticalSection();51Testing软件测试网%QtT7G%BcY
//删除关键代码段51Testing软件测试网s6X!n+F^&x
void DeleteMyCriticalSection();
a2C8w5Q6LHNo0//打印信息51Testing软件测试网kH8Z4y {/y%~
void PrintString(const CString& strInfo);
51Testing软件测试网F$gm"gj

51Testing软件测试网1wu_8]t0v d

DWORD WINAPI Thread1(LPVOID lpParameter);
{8]lc _Nj%aZwJ0DWORD WINAPI Thread2(LPVOID lpParameter);

2SyK!^ LA:H051Testing软件测试网fQiF'rw&f

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
G0[6UEb9oa0{51Testing软件测试网jIn7\)o4i~ J,ID
    int nRetCode = 0;

7U X~J5m%Lt0

b$\ mYEa U-Q0    // initialize MFC and print and error on failure51Testing软件测试网7]5xA5x t0} e
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
8J ~ p5G+\*]-At,m0    {
2eO0u{5A#k-f j0        // TODO: change error code to suit your needs
%oM1s2p:_K2^ d0        _tprintf(_T("Fatal Error: MFC initialization failed\n"));51Testing软件测试网(W+sd#U&{8U
        nRetCode = 1;
51Testing软件测试网d"M"TWj#j_

\zV-p%N$|*t\0        return nRetCode;
3^1F{"{y1F5Y0    }
51Testing软件测试网4xO2g3iTw

51Testing软件测试网B!b9c E9d:f1y+K9P

    //初始化关键代码段51Testing软件测试网2\+^N3xiBP)f(Uo
    InitMyCriticalSection();

"R Qe b fx'rv0

rF^;WAF4c ?0    //创建线程51Testing软件测试网'p L)e6G U/X7]p-BJ
    HANDLE hThread1 = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);51Testing软件测试网SarUsJ E&?
    HANDLE hThread2 = CreateThread(NULL, 0, Thread2, NULL, 0, NULL);

^;b E]*^U7Z051Testing软件测试网hl5?}I:Rx']

    //等待线程结束51Testing软件测试网FP+wu7E"T'\
    WaitForSingleObject(hThread1, INFINITE);
7kr5k JMF3tA%J0    WaitForSingleObject(hThread2, INFINITE);
51Testing软件测试网)s:i0k~Mp

51Testing软件测试网e$]!r!boS#go R9v

    //关闭线程句柄
9T%t$Mh:@f \9@0    CloseHandle(hThread1);51Testing软件测试网:[P9] u Q+yV{
    CloseHandle(hThread2);
51Testing软件测试网+G4[ ` T7b}^ F

51Testing软件测试网z(}2rx9vz

    //释放关键代码段
?rug kx x0    DeleteMyCriticalSection();
51Testing软件测试网w?%su(u]

cS4F/s6_yS8~~0    return nRetCode;
:U}T uHJI0}

-@l]:`0H051Testing软件测试网)k @ \ fv N1x

void InitMyCriticalSection()51Testing软件测试网1c^I"Fi
{
nr9f$etN0    InitializeCriticalSection(&cs1);
i$C(d4_G~)r0    InitializeCriticalSection(&cs2);
GddK&u9R+{u0    InitializeCriticalSection(&csprint);
*W Qn:d+c!o;M R|S0}

,pH0pZN051Testing软件测试网Ns}3c4@XS-LuW G

void DeleteMyCriticalSection()51Testing软件测试网Ps?%c{4Mw;QU5s
{51Testing软件测试网\jON3f/{
    DeleteCriticalSection(&cs1);
WJ,js Bk/w5X Kbtz0    DeleteCriticalSection(&cs2);51Testing软件测试网|1ik(N}1yF
    DeleteCriticalSection(&csprint);51Testing软件测试网~4t,Jj6x1zfp%I
}

1sFV2@5o(w051Testing软件测试网'fb)FcN;I}"U+_

DWORD WINAPI Thread1(LPVOID lpParameter)
1R6tO\c#m0{51Testing软件测试网7j;]og bB!}
    for (int i = 0; i < 5; i++)51Testing软件测试网l9KuOYf
    {51Testing软件测试网8Rhm8HdW [8@
        EnterCriticalSection(&cs1);51Testing软件测试网V%?b!GA|3^ Z)f
        Sleep(500);51Testing软件测试网*w2h0n2MO{q.L
        EnterCriticalSection(&cs2);
51Testing软件测试网v%I%\\!Dp^G B(i

O'Io*fLyg0        PrintString(_T("Thread1"));51Testing软件测试网6f/d"y1f&\&Da*ha

51Testing软件测试网dr}&\-Qh m ^

        LeaveCriticalSection(&cs2);51Testing软件测试网+j1rAK H2j
        LeaveCriticalSection(&cs1);51Testing软件测试网[!] PXGp.R1q
    }

r H4B.GI!t5\3i6fF051Testing软件测试网$aP(_ r.M)Hv1uU

    return 1;51Testing软件测试网$[} TX$M+o0M OL
}
51Testing软件测试网A4{P+C@,yAu?

Ye3D-c@8x0DWORD WINAPI Thread2(LPVOID lpParameter)51Testing软件测试网I9m:C:A [mw L
{
Ar-y ezj0    for (int i = 0; i < 5; i++)
1H/m;H|l0    {51Testing软件测试网6K]3Lk\-A:Kl
        EnterCriticalSection(&cs2);51Testing软件测试网~&Z^;q%cM(J2v9L!U
        Sleep(500);51Testing软件测试网X5u@mC#eP_"]
        EnterCriticalSection(&cs1);

Jb-RA&iv~051Testing软件测试网5{+E*cU5M"k2N

        PrintString(_T("Thread2"));

$Sg(mg Q B$WFr0

)F vW,h6D$Je0        LeaveCriticalSection(&cs1);51Testing软件测试网yvx+CK/p1g,p v^
        LeaveCriticalSection(&cs2);51Testing软件测试网E+d9q:^wy
    }

km5kX"IkG2Y.Op0

&s6e1gHOE i'Mz0    return 1;51Testing软件测试网YdIUwq
}
51Testing软件测试网m ]/V+y4e3iFt

51Testing软件测试网s\;K+MR!A]0ap h5z

void PrintString(const CString& strInfo)51Testing软件测试网E7t` vO b^/d aZ
{51Testing软件测试网#f Mid&EQ%@9A
    EnterCriticalSection(&csprint);51Testing软件测试网;~'x'd Qf t.^ W R
    wcout<<(const TCHAR*)strInfo<<endl;51Testing软件测试网y"M mB!d{1IrM
    LeaveCriticalSection(&csprint);51Testing软件测试网lx5Sj)U{
}

#o'g!? @!J8z4Lf"y,|!p0

Uv(q0ZZ3jU:oL2eg0  运行DeadLockTest.exe,程序挂起。

u.LF9u+@P|$|g1s;|+M051Testing软件测试网 T7E?;n~:|2am

  三、死锁检测

o8Q'\? Z)C b,B051Testing软件测试网2}n9T(m)WL?9iay V

  检测工具见《Windows核心编程》,第9章9.8.6节LockCop检测工具。

%NA)Tdl~*u0

1^!q%_Q'aa K.B0  工具源码地址:http://www1.wintellect.com/Resources/Details/86。

M P"y.p6qw0

-p6Wz%?#XIF0  LockCop可使用vs2010编译成功。51Testing软件测试网2c7w"l0E#C!MZ L)wb

51Testing软件测试网VYfRX9B s

  备注:该工具使用了Windows Vista/ 7提供的WCT API,故需要在Windows Vista/ 7系统运行LockCop检测工具。51Testing软件测试网 X)|g:}j9mx$P&n

_:[(?M&l1tUS0  检测,挂起的DeadLockTest.exe,得到线程信息。

+d'YY"X+J,@0

Z^ ]U#F*Q7[c0

  检测到程序挂起由死锁引起。51Testing软件测试网'R&r#olK vN1I

  线程4014:等待线程772、线程4012完成。
6W)YS9a,s&pWd!vk0  线程772:拥有关键代码段A,等待关键代码段B(被线程4012拥有)。51Testing软件测试网6aSD(e bMh8h
  线程4012:拥有关键代码段B,等待关键代码段A(被线程772拥有)。
51Testing软件测试网`K$t KH5\^_h0f{s

  线程772与4012互相等待,程序发生死锁现象。51Testing软件测试网mR#H*\;O2g"VOn


TAG:

 

评分:0

我来说两句

Open Toolbar