一个跟线程同步类似的问题,请各位帮帮看看出错原因有代码如下:C/C++ codebool g_IsReadThreadFinish tru
一个跟线程同步类似的问题,请各位帮帮看看出错原因
有代码如下:
C/C++ codebool g_IsReadThreadFinish = true;DWORD WINAPI ReadData(LPVOID lpParameter){ g_IsReadThreadFinish = false;//线程开始 //处理过程 .......; g_IsReadThreadFinish = true;//线程结束 return 0;}CXXXDlg::OnBnClickedBtnSelect(){ vector<string>::iterator iterator = vectorTab.begin(); while (iterator != vectorTab.end()) { .......; DWORD WINAPI ReadData(LPVOID lpParameter); HANDLE handle=CreateThread(NULL,0,ReadData,NULL,0,NULL); CloseHandle(handle); g_IsReadThreadFinish = false; while (!g_IsReadThreadFinish) { Sleep(200); } iterator++; }}
主线程的OnBnClickedBtnSelect()函数要连续几次通过创建相同线程进行处理,线程参数不一样
1.建线程后,将g_IsReadThreadFinish = false;
2.在线程处理函数中g_IsReadThreadFinish = false;
3.线程处理函数结束,g_IsReadThreadFinish = true;
4.主现成开启线程后进入
C/C++ codewhile (!g_IsReadThreadFinish) { Sleep(200); }
等待;
这样看起来没有出问题,
可是调试的时候,怎么第一个线程都还没处理完,主线程又开启第二个线程了呢?
请指点!!!
[解决办法]开始时没注意你的问题是创建了多于一个的线程,这估计是有内存越界或者使用了错误的指针而破坏了g_IsReadThreadFinish的值。
[解决办法]因为Sleep的功能是暂停当前线程的CPU使用功能,切换到其他的线程去执行,你现在的代码很可能执行在主线程的while-Sleep循环中,每次执行到Sleep,然后线程切换到你创建的线程,而系统会发现所创建的线程执行的时间过长,系统又把CPU调度给你的主线程,这里就形成了一个来回的死循环。
我之前的回复可能没考虑好,但仍然建议你用WaitForSingleObject方法来等待线程结束
[解决办法]在c++中编译时,如果发现在函数体内部没有改变某个变量的值,如g_IsReadThreadFinish,则函数体可能忽略该项值的检测,直接用初始值来代替,也就是说在OnBnClickedBtnSelect()函数体内,g_IsReadThreadFinish永远被编译成了false.试试使用volatile bool g_IsReadThreadFinish = true;替换原来的bool g_IsReadThreadFinish = true;
[解决办法]在线程中访问控件可能会导致错误,因为VC中的控件都不是线程安全的,最好是通过SendNotifyMessage或者PostMessage,向控件发送消息来刷新显示,或者向窗口发送自定义消息,来处理。
[解决办法]根据你的代码中得到的提示信息,你应该不能用WaitForSingleObject函数,原因在于这个函数是阻塞主线程的消息循环来等待,而你的ReadData线程会去操作CListCtrl来显示数据,这样会导致两个线程都阻塞住。
你的问题需要判断你的线程函数ReadData会和界面的相关吗?或者说这个函数会涉及到主线程的消息泵吗?
如果你的回答是不,那么可以才可以用WaitForSingleObject来等待,我看你对WaitForSingleObject的用法好像也有问题。
你应该用MsgWaitForMultipleObjects,这个函数才是既等待内核对象,又处理消息的。下面的while循环才是用来实现你的真正的等待,代码段仅供参考
while(TRUE)
{
DWORD result ;
MSG msg ;
result = MsgWaitForMultipleObjects(1, &readThreadHandle,
FALSE, INFINITE, QS_ALLINPUT);
if (result == (WAIT_OBJECT_0))
{
break;
}
else
{
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
DispatchMessage(&msg);
}
}
[解决办法]可是调试的时候,怎么第一个线程都还没处理完,主线程又开启第二个线程了呢?
——————
HANDLE handle=CreateThread(NULL,0,ReadData,NULL,0,NULL);
CloseHandle(handle);
g_IsReadThreadFinish = false;
while (!g_IsReadThreadFinish)
{
Sleep(200);
}
——————
注意:CloseHandle(handle)并不是结束线程,而是释放线程句柄handle的资源。另外,进程的主线程有比子线程更高的优先级。
所以,上面代码中,线程创建后,还没等线程结束,而仅仅是当线程句柄释放后就急急地把g_IsReadThreadFinish设为false了。从你的描述来看,g_IsReadThreadFinish = false;这一句应当放到线程处理函数ReadData执行完毕前的最后一句处。
[解决办法]
[解决办法]如果楼主的数据线程里面没有去操作CListCtrl,是可以用WaitForSingleObject的,但是线程中一旦用了SendMessage之类的方法就不行了
[解决办法]多线程同时操作一个变量会出问题的