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

来源:互联网 发布:淘宝秒杀网址 编辑:程序博客网 时间:2024/05/09 11:36

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

前不久公司在做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;
}


原创粉丝点击