)::WaitForSingleObject
来源:互联网 发布:阿里云服务器使用手册 编辑:程序博客网 时间:2024/05/20 17:27
转自 http://topic.csdn.net/u/20071011/22/b3e17e2d-b6ca-4484-9e19-7354e47ea10c.html
主要学习到两点:
1)::WaitForSingleObject(m_hThread,INFINITE);
主要功能同志 线程m_hThread句柄 有消息了(相当于信号量),第二个参数表示死等
2)不建议此接口用在主线程。
3)对话框的头文件中:
#define YOURMESSAGE WM_USER +1
在//}}AFX——
与DECLARE——MESSAGE——MAP()
之间加上
afx_msg LRESULT OnYourMessage(WPARAM wParam ,LPARAM lParam);
然后在CPP中:
在BEGIN——MESSAGE_MAP()
中的//}}AFX_MSG_MAP
与EMD_MESSAGE_MAP()之间加上
ON_MESSAGE(YOURMESSAGE,OnYourMessage)
然后定义OnYourMessage()
然后就可以在你的线程中POSTMESSAGE()了
我做了如下的一个小实验程序:
在VC中创建一个MFC对话框工程Test,添加两个按钮IDC_BUTTON_CREATE_THREAD和IDC_BUTTON_EXIT_THREAD,分别用来控制创建子线程和结束子线程。它们的响应函数如下:
void CTestDlg::OnButtonCreateThread()
{
// TODO: Add your control notification handler code here
DWORD dwThreadId = 0;
if (m_hThread == NULL)
{
m_hThread = ::CreateThread(0,0,ThreadProc,LPVOID(this),0,&dwThreadId);
}
}
void CTestDlg::OnButtonExitThread()
{
// TODO: Add your control notification handler code here
if (m_hThread != NULL)
{
// Set the flag that the thread must be stopped
m_bThreadStopping = TRUE;
// Wait until the watcher thread has stopped
::WaitForSingleObject(m_hThread,INFINITE);
// The thread has stopped
m_bThreadStopping = FALSE;
// Close handle to the thread
::CloseHandle(m_hThread);
m_hThread = 0;
}
}
上面的代码中m_hThread是保存子线程句柄的CTestDlg成员变量,m_bThreadStopping是CTestDlg的静态成员变量,用来指示子线程退出。子线程的代码如下:
DWORD WINAPI CTestDlg::ThreadProc( LPVOID lpParameter )
{
LARGE_INTEGER nStartCount, nCurCount;
while (!m_bThreadStopping)
{
::QueryPerformanceCounter(&nStartCount);
do
{
::QueryPerformanceCounter(&nCurCount);
} while (nCurCount.QuadPart < nStartCount.QuadPart + 1000);
if (!m_bThreadStopping)
{
::SendMessage(((CTestDlg *)lpParameter)->GetSafeHwnd(), WM_APP+1, 0, 0);
}
}
return 999;
}
子线程是CTestDlg的静态成员函数,它的功能实际是每隔一定时间向主线程(UI线程)发送消息,相当于一个定时器。为达到准确的时间控制,消息发送用了SendMessage(),而不是PostMessage()。主线程中的消息响应如下:
LRESULT CTestDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
static UINT uCount = 0;
if (message == WM_APP + 1)
{
SetDlgItemInt(IDC_STATIC, uCount, FALSE);
uCount++;
}
else
{
return CDialog::WindowProc(message, wParam, lParam);
}
}
就是在IDC_STATIC静态文本控件中显示接收到子线程消息的次数。
问题就在于,有的时候当点击“结束线程”(也就是IDC_BUTTON_EXIT_THREAD按钮)时,程序再不响应用户操作,但静态文本控件中的计数值不变,疑似进入死锁状态。当子线程发送消息的间隔时间缩短时,这种现象更严重。我怀疑有可能是下面的情况发生了,就是主线程在等待子线程结束的时候被挂起(在执行WaitForSingleObject()时),但是子线程同时又在等待主线程返回消息处理结果(即子线程正在执行SendMessage())。但是我又觉得在子线程正在执行SendMessage()函数时,主线程应该不会响应用户点击“结束线程”的事件才是,因为SendMessage()发送的消息是Non-queued消息,而点击“结束线程”的消息是queued消息,它被放在消息队列中,至少应该等到子线程的SendMessage()调用主线程窗口的WindowProc()处理完子线程发送的消息之后才会被处理。这样说来,上面的死锁情形就不应该发生。想了一整天没弄明白为什么会发生这种现象,还望高手指点,在此先谢谢了!
- )::WaitForSingleObject
- WaitForSingleObject()
- 多线程编程WaitForSingleObject()
- WaitForSingleObject()函数
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject
- WaitForSingleObject()
- WaitForSingleObject
- WaitForSingleObject
- IIS 重启命令
- 8086/8088汇编指令系统剖析(四)
- DirectX9 SDK Samples(20) HDRDemo Sample(2)
- MOVE语句。
- READ1.
- )::WaitForSingleObject
- 黑马程序员--java多线程
- 所谓经验,半数扯淡
- spring整合quartz
- Linux RTC 驱动模型分析
- android 修改文件属性(U960S删除快门声实例)
- 对在校学生的想从事嵌入式行业的几点建议
- spring 依赖注入一
- While循环