MFC【17-3】线程和线程同步化
17.3小知识点
17.3.1消息泵
编写一个应用程序,让它响应某菜单命令,画几千个椭圆。
void CMFC线程View::OnStartDrawing(void)
{
m_bQuit=FALSE;
for(int i=;i<NUMELLIPSES&&!m_bQuit;i++)
{
DrawRandomEllipse();
if(!PeekAndPump())
break;
}
} void CMFC线程View::OnStopDrawing(void)
{
m_bQuit=TRUE;
} bool CMFC线程View::PeekAndPump(void)
{
MSG msg;
while(::PeekMessage(&msg,NULL,,,PM_NOREMOVE)){
if(!AfxGetApp()->PumpMessage()){
::PostQuitMessage();
return FALSE;
}
}
LONG 1Idle=;
while(AfxGetApp()->OnIdle(1Idle++));
return TRUE
}
PeekAndPump在一个消息循环中定制另一个消息循环。它在OnStartDrawing中for语句的循环终点处被调用。如果::PeekMessage指示队列中有消息等待,则PeekAndPump首先调用CWinThread::PumpMessage提取消息和分派消息。如果PumpMessage返回0,则表示提取和分派的最后一个消息是WM_QUIT消息。而因为只有用“主”消息循环提取WM_QUIT消息,应用程序才能结束,所以该消息要求特殊处理。因此如果PumpMessage返回0,PeekAndPump就会把另一个WM_QUIT消息发往队列;如果PeekAndPump返回0,就会把另一个WM_QUIT消息发往队列;如果PeekAndPump返回0,OnStartDrawing中的for语句循环就会失败。如果WM_QUIT消息不提示提前退出,那么通过在返回之前调用应用程序对象的OnIdle函数,PeekAndPump就可以模仿主程序的闲置机制。
17.3.2执行其他进程
Win32执行进程。下列语句执行c:\\WINDOWS\Notepad.exe.
STARTUPINFO si;
::ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);
PROCESS_INFORMATION pi; if(::CreateProcess(NULL,_T("C:\\Windows\\Notepard"),NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,
NULL,NULL,&si,&pi)){
::CloseHandle(pi.hThread);
::CloseHandle(pi.hProcess);
}
::CreateProcess是一个通用函数,它获取可执行文件的名字(和路径),然后加载并执行他,如果可执行文件名中的驱动器和目录名被省略,则系统自动在Windows目录,Windows系统目录,当前路径下的所有目录和选中的其他位置中搜索该文件。文件名也可以包含命令行参数,如:
“C:\\Windows\\Notepad C: \\ Windows\\ Desktop\\Ideas.txt"
::CreatProcess将进程的关键信息填充在PROCESS_INFORMATION结构中。相关信息包括:进程句柄(hProcess)和进程中主线程的句柄(hThread)。在进程启动后,要用::CloseHandle关闭这些句柄。如果CreateProcess返回非零值,则意味着进程启动成功。因为Win32是一部启动、一部执行的,所以CreateProcess不必等到进程结束后再返回。如果您希望启动另一个进程,并暂停当前进程知道该进程启动的进程结束,则您可以对该进程句柄调用::WaitForSingleObject
STARTUPINFO si;
::ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);
PROCESS_INFORMATION pi; if(::CreateProcess(NULL,_T("C:\\Windows\\Notepard"),NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,
NULL,NULL,&si,&pi)){
::CloseHandle(pi.hThread);
::WaitForSingleObject(pi.hProcess,INFINITE);
::CloseHandle(pi.hProcess);
}
进程和线程一样都有退出代码。如果::WaitForSingleObject没有返回WAIT_FAILED,则可以调用::GetExitCodeProcess获取进程的退出代码。
有时需要启动进程并等待足够长的时间后,才能确保进程已开始并相应用户输入。例如:如果进程A启动进程B,而进程B又创建了一个窗口,这是,如果进程A要给窗口发送消息,他就不得不等到CreateProcess返回,留给进程B足够的时间创建窗口并开始处理消息。通过Win32::WaitForInputIdle函数可以解决这个问题。
STARTUPINFO si;
::ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb=sizeof(STARTUPINFO);
PROCESS_INFORMATION pi; if(::CreateProcess(NULL,_T("C:\\Windows\\Notepard"),NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,
NULL,NULL,&si,&pi)){
::CloseHandle(pi.hThread);
::WaitForInputIdle(pi.hProcess,INFINITE);
::CloseHandle(pi.hProcess);
}
17.3.3文件改变通知
::WaitForSingleObject的HANDLE参数可以是“文件改变通知句柄”。Win32 API包含一个函数::FindFirstChangeNotification,只要给定目录或他的子目录发生了变化,例如文件被重命名或删除,或创建了一个新目录,该函数都能返回一个句柄,通过该句柄您可以启动一个被阻塞的线程。
如果想改善11章中的Wanderer应用程序,使文件系统的而变化难呢过立刻反应在左面或右面的窗格中。为此,最有效的方法是启动一个后台线程,并使它在一个或多个文件改变通知句柄上处于阻塞状态。下面是用来监视驱动器C:的线程的线程函数:
UINT ThreadFunc(LPVOID pParam)
{
HWND hwnd=(HWND)pParam;//Window to notify
HANDLE hChange = ::FindFirstChangeNotification(_T("C:\\"),
TRUE,FILE_NOTIFY_CHANGE_FILE_NAME);// FILE_NOTIFY_CHANGE_DIR_NAME);
if(hChange==INVALID_HANDLE_VALUE){
TRACE(_T("Error:FindFirstChangeNotification failed\n"));
return(UINT) -;
}
while(){
::WaitForSingleObject(hChange,INFINITE);
::PostMessage(hwnd,WM_USER_CHANGE_NOTIFY,,);
::FindNextChangeNotification(hChange);//Reset
}
::FindCloseChangeNotification(hChange);
return ;
}
MFC【17-3】线程和线程同步化的更多相关文章
- MFC【17-2】线程和线程同步化
17-2线程同步 Windows支持4中类型的同步对象,可以用过来同步由并发运行的线程执行的操作: 临界区 互斥量 事件 信号量 MFC在名为CCriticalSection\CMutex\CEven ...
- MFC【17-1】线程和线程同步化
17.1线程 对于Windows来说所有的线程都是一样的,但MFC却把线程区分为两种类型:User Interface(UI) threads(用户界面(UI)线程)和Worker threads(工 ...
- C#高级编程笔记(17至21章节)线程/任务
17 Visual Studio 2013 控制台用Ctrl+F5可以显示窗口,不用加Console.ReadLine(); F5用于断点调式 程式应该使用发布,因为发布的程序在发布时会进行优化, 2 ...
- 用MFC库函数AfxBeginThread()来创建线程
在进行多线程程序设计的时候,我们经常用到AfxBeginThread函数来启动一条线程该函数使用起来非常的简单方便,其定义如下: 1.函数原型 CWinThread* AfxBeginThread( ...
- C#中的线程(二) 线程同步基础
1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具: 简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...
- Java线程:线程状态的转换
Java线程:线程状态的转换 一.线程状态 线程的状态转换是线程控制的基础.线程状态总的可分为五大状态:分别是生.死.可运行.运行.等待/阻塞.用一个图来描述如下: 1.新状态:线程对象已 ...
- 基础学习day12--多线程一线程之间的通信和常用方法
一.线程之间的通信 1.1.线程之间的通信方法 多个线程在处理统一资源,但是任务却不同,这时候就需要线程间通信. 等待/唤醒机制涉及的方法: 1. wait():让线程处于冻结状态,被wa ...
- 基础学习day11--多线程一线程的创建,运行,同步和锁
一.线程基本概述 1.1.进程和线程 进程:一个应用程序一般都是一个进程,正在进行的程序 每一个进程最少都有一个线程,都有一个执行顺序,该顺序是一个执行路径或者一个控制单元 线程:进程中一个独立的控制 ...
- C#中的线程(中)-线程同步
1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具: 简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...
随机推荐
- redis之(十六)redis的cluster集群环境的搭建,转载
最近redis已经比较火了,有关redis的详细介绍,网上有一大堆,我这里只作简单的介绍,然后跟大家一起学习Redis Cluster 3.0的搭建与使用.Redis是一款开源的.网络化的.基于内存的 ...
- LCA离线算法Tarjan的模板
hdu 2586:题意:输入n个点的n-1条边的树,m组询问任意点 a b之间的最短距离 思路:LCA中的Tarjan算法,RMQ还不会.. #include <stdio.h> #inc ...
- 辨析各类web服务器:Apache/Tomcat/Jboss/Nginx/等,还有Nodejs
先说一下各类服务器能干啥,特点是啥,然后在区分他们的类别. (1)Apache: Apache是指Apache软件基金会的Apache HTTP Server, 它能够接收http请求,然后返回各类资 ...
- 如何修改wordpress的.po和.mo配置文件
如果我们在定制个性化WP模版时,若要修改默认语言包中文字描述,则可以通过修改zh_CN.mo和zh_CN.po来实现,但mo文件是不能直接修改编辑,因此就只能修改po文件了,po文件不能通过我们常用的 ...
- 【机器学习】k-近邻算法以及算法实例
机器学习中常常要用到分类算法,在诸多的分类算法中有一种算法名为k-近邻算法,也称为kNN算法. 一.kNN算法的工作原理 二.适用情况 三.算法实例及讲解 ---1.收集数据 ---2.准备数据 -- ...
- 启动Tomcat报错 “A child container failed during start”
严重: A child container failed during startjava.util.concurrent.ExecutionException: org.apache.catalin ...
- 【招聘需求】前端开发/PHP工程师【往全栈发展】
1.熟悉html.css,了解javascript2.熟悉任何一种服务端编程语言(php.python.java.asp.jsp.c.c++.c#,go等等)3.热爱工作,接受加班者优先 我们是公司内 ...
- POJ 1062 昂贵的聘礼 【带限制的最短路/建模】
年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低要求.酋长说:" ...
- css总结——position
CSS(Cascading Style Sheet),中文翻译为层叠样式表,是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言.在css控制页面中,主要有四种样式:行内样式(style ...
- 伤逝——shoebill关于noip2017的手记
如果我能够,我要写下我的悔恨和悲哀,为机房爆炸的dalao们,为自己. jzyz的被遗忘在实验楼里的机房依然喧闹而空虚,时光过得真快,我学oi,仗着她逃过班级的寂静,已经满一年了.事情又这么不凑巧,我 ...