【发布时间】:2015-06-25 08:05:53
【问题描述】:
我有一个带有 MFC 的 GUI 应用程序。我正在使用 AfxBeginThread() 启动线程来处理一些数据。而且我在访问线程中的主对话框时遇到问题:
通过这个结构,我将主对话框处理程序和指向主 dlg 对象的指针传递给线程。但在 strcpy() 行调试器停止并显示 pDlg->0x430f0020 {CTabDlg hWnd=???}
typedef struct {
LPVOID myHandle;
LPVOID myPointer;
} sParamData;
UINT WorkerThreadProc_type2( LPVOID Param )
{
UpdInfo info;
sParamData *s;
s = (sParamData*)Param;
HWND hMainHandle = (HWND) (*s).myHandle;
CtabDlg* pDlg = (CtabDlg*)(*s).myPointer;
strcpy(apikey, pDlg->m_sVar);
...
}
我尝试了 XP 和 Windows 7 操作系统。在 XP 中它总是崩溃,但在七中它可以工作。这就是我将结构传递给线程的方式:
sParamData s;
s.myHandle = (HWND)GetSafeHwnd();
s.myPointer = (CtabDlg*) this;
if(CurrTab == 1)
{
AfxBeginThread(WorkerThreadProc_type2, &s, THREAD_PRIORITY_NORMAL,0,0,NULL);
pPage2->GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
感谢您的宝贵时间!
【问题讨论】:
-
一些与程序崩溃无关的备注:
sParamData不应包含LPVOID类型,而是实际类型,即HWND和CtabDlg。这将避免对这些类型的所有强制转换。此外写s->myHandle而不是(*s).myHandle,它是等价的,但没有C程序员写(*s).而不是s->。 -
它可能是race condition,即在某些时候
CTabDlg不再存在,但您的线程不知道这一点。 -
@Michael Walz,CTabDlg 是一个主对话框,一直存在,而且它总是以某种方式在 Windows 7 中工作。
-
好的,但是在某些情况下,比赛条件很可能会在一个平台上导致问题,但在另一个平台上却没有,顺便说一句:你在哪里声明
sParamData *s? -
在 W7 上,线程似乎开始得早一点,所以当你从线程中读取变量
s时,它仍然存在,而在 XP 上,线程似乎开始得晚一点,s当线程尝试读取它时不再存在。竞争条件的典型案例。
标签: c++ multithreading visual-c++ mfc