fla*_*iu2 5 c++ mfc multithreading thread-safety visual-c++
从线程发送CString通过的安全/最佳方式PostMessage是什么?要CString在堆上创建并在接收者收到此信息时进行清理CString?
解决方案1:在线程中:
CString* pError = new CString(_T("Unknown error"));
::PostMessage(...(LPARAM)pError);
Run Code Online (Sandbox Code Playgroud)
在主线程中,在 GUI 的某个地方:
CString* pError = (CString*)lParam;
GetDocument()->DoSomething(*pError);
delete pError;
Run Code Online (Sandbox Code Playgroud)
解决方案 2:
或者,将CString对象保留为CThread类内部的成员变量?
class CPlanThread : public CThread [: public CObject]
{
public:
DECLARE_DYNAMIC(CPlanThread)
...
protected:
CString* m_pMessage;
};
Run Code Online (Sandbox Code Playgroud)
和
CPlanThread::CPlanThread()
:m_pMessage(NULL)
{
m_pMessage = new CString(_T(""));
}
CPlanThread::~CPlanThread()
{
if(NULL != m_pMessage)
delete m_pMessage;
}
Run Code Online (Sandbox Code Playgroud)
和线程中的某个地方:
::PostMessage(m_hWndMain, WMU_NOTIFYTHREAD, 0, (LPARAM)m_pMessage);
Run Code Online (Sandbox Code Playgroud)
在主线程中,在 GUI 的某个地方:
CString* pError = (CString*)lParam;
GetDocument()->DoSomething(*pError);
Run Code Online (Sandbox Code Playgroud)
以上两种解决方案都安全吗?感谢您的任何解释。
第一个选择是更安全的选择。*这可能导致资源泄漏的唯一原因是,如果调用::PostMessage失败,并且您没有在发送方中进行清理。请注意,这不会导致崩溃。
第二种选择会产生竞争条件,因为您持有一个指针,而您打算转移其所有权。如果 GUI 线程在线程对象被销毁后尝试访问该字符串,则您正在访问随机内存。如果幸运的话,这可能会导致立即崩溃。
根据您的具体用例,您可能需要考虑使用第三种替代方案:使用CString具有自动存储持续时间和通过消息发送进行线程同步的对象,例如:
CStringW err( L"Unknown error" );
::SendMessage( ..., (LPARAM)&err );
Run Code Online (Sandbox Code Playgroud)
只要字符串对象位于其消息处理程序中,接收线程就可以使用该字符串对象,并且发送者将自动清理资源。