1、由于历史原因,标准C/C++库在开始时并没有正对多线程做考虑(比如使用了一些全局变量),
在VC++中对标准库做了多线程安全扩展
2、要利用这些扩展就需要使用VC++扩展库提供的创建线程函数_beginthread,_beginthradEx等
函数来替代Windows的原始API--CreateThread
3、因为这些创建函数在内部考虑了多线程安全初始化C/C++标准库,使用这些替代函数创建的线程调用
C/C++时将时多线程安全的(比如:利用TLS等特性改进全局变量)
4、如果只是API的话,那么不存在什么问题(GRSLib库是一个基本不使用C/C++标准库的纯API式的库,
最终是否使用了C/C++标准库由调用者子集决定,但是其线程创建还是使用了_beginthreadex函数)
5、但是若需要调用C/C++库函数的话都建议使用扩展的创建函数替代品(建议使用_beginthreadex)
使用C++类非静态成员函数创建线程
1、如果C++类的非晶态成员是__stdcall调用约定的,那么调用次成员函数时,即使this指针也会入栈
2、而CreateThread(包括_beginthread和_beginthreadex)方法都会传递一个线程函数参数
3、利用这一特征可以将this指针传入,并将指向成员函数的指针当作线程入口参数(适当做下函数指针的
强制类型转换)
C++类封装线程的问题
因为线程C++对象和实际代表的生命周期的不同,所以有可能在对象已经析构之后,线程本身还在运行,还可能调用
到线程对象的方法
因此一般的策略时将C++的线程对象分配到堆上,并当线程函数结束的时候,由线程对象内部自己来释放自己
#include
#include
#include
#include
#define GRS_USEPRINTF() TCHAR pBuf[1024]={}
#define GRS_PRINTF(...)\
StringCchPrintf(pBuf, 1024, __VA_ARGS__); \
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), pBuf, lstrlen(pBuf), NULL, NULL);
class ThreadClass
{
protected:
HANDLE m_hThread;
DWORD m_dwThreadID;
public:
ThreadClass(BOOL bCreate = TRUE)
:m_hThread(NULL)
,m_dwThreadID(0)
{
GRS_USEPRINTF();
GRS_PRINTF(_T("ThreadClass对象[A:0x%08x]初始化在线程[ID:0x%x]中\n"),
this,GetCurrentThreadId());
if (bCreate)
{
CreateThread();
}
}
virtual ~ThreadClass()
{
}
protected :
UINT __stdcall ThreadProc(LPVOID lpParameter)
{
if (InitThread())
{
Run();
}
return ExitThread();
}
public:
BOOL CreateThread(DWORD dwStackSize = 0)
{
typedef UNIT (__stdcall *StdProc)(LPVOID);
typedef UNIT (__stdcall ThreadClass::*ThreadObject)(LPVOID);
ThreadObject pThis = &ThreadClass::ThreadProc;
GRS_USEPRINTF();
m_hThread = (HANDLE)_beginthreadex(NULL, dwStackSize,
*(StdProc*)&pThis, this, CREATE_SUSPENDED, (UINT*)&m_dwThreadID); //指向类成员函数的指针
if (-1L == (LONG)m_hThread)
{
GRS_PRINTF(_T("_beginthreadex发生错误"));
return FALSE;
}
ResumeThread(m_hThread);
return -1L != (LONG)m_hThread;
}
public:
virtual BOOL InitThread()
{
GRS_USEPRINTF();
GRS_USEPRINTF(_T("ThreadClass对象[A:0x%08x]线程[H:0x%08x ID:0x%x]初始化\n"),
this,m_hThread,m_dwThreadID);
return TRUE;
}
virtual BOOL Run()
{
GRS_USEPRINTF();
GRS_USEPRINTF(_T("ThreadClass对象[A:0x%08x]线程[H:0x%08x ID:0x%x]运行\n"),
this, m_hThread, m_dwThreadID);
return TRUE;
}
virtual BOOL ExitThread()
{
GRS_USEPRINTF();
GRS_USEPRINTF(_T("ThreadClass对象[A:0x%08x]线程[H:0x%08x ID:0x%x]退出\n"),
this, m_hThread, m_dwThreadID);
return TRUE;
}
};
int _tmian()
{
ThreadClass thd;
_tsystem(_T("PAUSE"));
return 0;
}