多线程程序调试个人经验总结
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;
}
前不久公司在做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;
}
相关文章推荐
- keil程序在外部RAM中调试的问题总结(个人的一点经验总结)
- keil程序在外部RAM中调试的问题总结(个人的一点经验总结)
- 使用gdb调试多线程程序总结
- 使用gdb调试多线程程序总结
- gdb调试多线程程序总结
- NesC学习经验总结:第三篇 如何调试NesC程序
- 使用gdb调试多线程程序总结
- 使用gdb调试多线程程序总结
- evc++程序的调试经验总结
- 个人多线程程序设计经验总结
- 黑马程序员--07.集合框架--并发访问异常理解:一个单线程程序的多线程运行思想【个人总结】
- 使用gdb调试多线程程序总结
- 使用gdb调试多线程程序总结
- gdb调试多线程程序总结
- gdb调试多线程程序总结
- gdb调试多线程程序总结
- GDB调试多线程程序(总结)
- 个人多线程程序设计经验总结
- linux系统下调试程序经验总结
- 项目管理心得:一个项目经理的个人体会、经验总结 (供自己参考)