您的位置:首页 > 其它

多线程程序调试个人经验总结

2010-02-27 09:40 856 查看
对于多线程出现的问题,一般很难调试跟踪程序出现的问题。以下就个人工作经验跟大家一些分享关于多线程调试的方法,由于本人水平有限,如有不妥之处,还望大家多提宝贵意见.

前不久公司在做failover的时候agent出现两种症状,这两种症状在实际的开发中也是经常出现的.

第一:线程控制的agent状态不能正常切换,在界面上看到的现象就是agent状态一直保持为staring.

第二:线程之间没有同步.异步相互转发消息

当第一眼看见界面上状态一直没有改变,应该考虑有两种可能,

A:这个线程有可能发生了死锁,[解决这个问题可以参考:http://blog.csdn.net/coding_hello/archive/2008/12/10/3487793.aspx#977644]

B:这个线程没有运行到最终的就绪状态,这个线程在运行的数据流中也许在什么地方中断了.永远得不到执行的机会.

对于B的解决方案时:

先查看日志,看控制该agent的状态是由哪个线程来控制的,观察该线程的控制流.发现该线程一直在timewait,原因是因为该线程没有启动之前,另外一个现成将他kill掉了,

然后该线程发送一个signal信号,同时设置退出线程的条件变量为 bRun = FALSE;由于运行agent状态切换的线程还没有启动,所以所有的发送信号及退出线程的标志都没有

起到作用.

模拟上述情形B参考代码如下:

#include "stdafx.h"

// multeThreadTraining.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include <WINDOWS.H>

#include <iostream>

#include <sstream>

using namespace std;

class CThread;

DWORD WINAPI thrdFunc(LPVOID pThread);

void printfLogMessage(std::string strInfo);

class CThread

{

public:

    virtual void run()=0;

    virtual void terminate()=0;

    //protected:

    void start();

private:

    HANDLE hThread;

};

void CThread::start()

{

    /*

    HANDLE CreateThread(

    LPSECURITY_ATTRIBUTES lpThreadAttributes,

    SIZE_T dwStackSize,

    LPTHREAD_START_ROUTINE lpStartAddress,

    LPVOID lpParameter,

    DWORD dwCreationFlags,

    LPDWORD lpThreadId

    );

    //*/

    hThread = ::CreateThread(NULL, 0, thrdFunc, this, 0, 0);

}

DWORD WINAPI thrdFunc(LPVOID pThread)

{

    // assert(pThread != NULL);

    CThread *trd = (CThread*)pThread;

    trd->run();

    return 1;

}

class CSateSwitchThread : public CThread

{

public:

    CSateSwitchThread() : m_bRun(false)

    {

        /*

        HANDLE CreateSemaphore(

        LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

        LONG lInitialCount,

        LONG lMaximumCount,

        LPCTSTR lpName

        );

        //*/

        m_semaphore = ::CreateSemaphore(NULL, 0, 1, NULL);

    }

    virtual void run();

    virtual void terminate();

private:

    volatile bool m_bRun;

    HANDLE m_semaphore;

};

void CSateSwitchThread::run()

{

    printfLogMessage("enter run");

    m_bRun = true;

    while(m_bRun)

    {

        DWORD dwResult = WaitForSingleObject(m_semaphore, 2000);

        if (WAIT_OBJECT_0 == dwResult)

        {

            printfLogMessage("we get signal successfully");

        }

        else if (WAIT_TIMEOUT == dwResult)

        {

            printfLogMessage("the expire time is ok");

        }

        printfLogMessage("CSateSwitchThread::run");

        if (!m_bRun)

        {

            printfLogMessage("exit run");

            break;

        }

    }

}

void CSateSwitchThread::terminate()

{

    m_bRun = false;

    /*

    BOOL ReleaseSemaphore(

    HANDLE hSemaphore,

    LONG lReleaseCount,

    LPLONG lpPreviousCount

    //*/

    ReleaseSemaphore(m_semaphore, 1, NULL);

}

void printfLogMessage(std::string strInfo)

{

    std::ostringstream ostr;

    ostr<<"["<<GetCurrentThreadId()<<"]"<< strInfo.c_str()<<endl;

    cout<<ostr.str()<<endl;

}

int _tmain(int argc, _TCHAR* argv[])

{

    CSateSwitchThread SWT;

    SWT.start();

    // Sleep(5000);

    SWT.terminate();

    while(1)

    {

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息