分享
 
 
 

No MFC 编程05 - 进程 > 线程 > 消息队列,三者的包含关系

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

(以下内容对于初入门的人是不能或缺的)

进程和线程,线程和消息队列,他们之间确实是有包含的关系。 如果让我按大小排序,我会排成象题目的那样。( 不过大概有人会说,消息队列怎么能跟进程、线程混为一谈呢?)

简单的来说,什么是进程?什么是线程?打个比方,你的程序要执行,操作系统就会把你的 exe 文件加载到内存中,那就生成一个进程了(当然还包含分配到的资源等); 对于线程,你可以理解成是一个程序里的不同部分,这有点类似函数,所不同的是各个线程是同时执行的。 例如,你的主线程创建了另一个副线程,那么这两个线程是同时在工作的,不存在 调用 - 返回 的概念。 一个进程里可以有多个线程在执行,称为执行实例。

根据我的理解,进程应该是比较大的概念, 一个进程开始时至少会有一个主线程 ( 即主执行实例 ) ,这是在系统加载你的程序的时候所创建的主执行流程。一般对外部来说只能看到进程,例如在 Win2000 的任务管理器里面查看到的只有进程 ( Process ) 而已。

用 Ctrl + Shift + ESC 可以在 Win2000 里调出任务管理器。

而消息队列则是与线程 ( Thread ) 相关的,换句话说,一个线程只能有一个消息队列 ( queue ) 与之相对应。 这跟之前说的有点不同,一个进程里面可以有多个线程;但是一线程里面就不能超出一个消息队列 ( Win98 里面甚至可以没有消息队列 )。

消息队列是在什么时候生成的呢? 在 Win2000 里面,从一开始创建线程就已经有了。( 在 Win98 里,我估计是在创建过窗口之后,留给你去证实 )

说了半天,可能一些刚入门的朋友还不知道什么是消息队列呢? 其实,Windows 操作系统是一个基于事件驱动的系统。它把握诸如鼠标,键盘输入等东西化为事件代号,发送到你的程序的消息队列里面去,你的程序则每次提取一个事件,根据事件的性质执行相应的操作,不断循环而已。

微软提倡编程人员使用事件驱动的编程方法。 你也可以向自己线程的消息队列里发送假消息,自己骗自己也是可以的 ( 虚伪 ) !使用 PostThreadMessage 函数即可。

编出多线程的程序其实并不难,难点其实在于线程同步 ( 线程间协调工作 ),下面的源程序正是为了简单介绍多线程编程的。

( 阅读的时候不要忘了主线程的入口是 WinMain 函数 )

// File Name: WinMain.cpp

#define WIN32_LEAN_AND_MEAN // Say No to MFC !!

#include <windows.h>

char Temp[77] = "";

// 我自定义的新线程入口 MyThread 函数

DWORD WINAPI MyThread( LPVOID lpParameter )

{

long ThrVal = 1 ;

for (ThrVal = 1; ThrVal < 16; ThrVal++ )

{

wsprintf( Temp , "这是副线程第 %ld 次显示" , ThrVal );

MessageBox( NULL, Temp, "第二线程内容 __CopyRight - `海风 ", MB_OK | MB_TOPMOST );

}

return 1 ;

} // 副线程结束

// Name: WinMain() 主线程的入口

// ------ ---------- ----------- ---------

int WINAPI WinMain( HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow )

{

DWORD dwThreadId, dwMyThrdParam = 1; // 第一个参数是新线程的 ID 号,第二个参数略

HANDLE hThread; // 副线程的 handle

// 调用函数创建新的线程,新线程入口是 MyThread 函数

hThread = CreateThread( NULL, // 没有 (或默认) 的属性

0, // 使用默认堆栈大小

MyThread, // 我的线程入口函数

&dwMyThrdParam, // argument to thread function

0, // 使用默认 creation flags

&dwThreadId); // Win98 里不能省略

// 已经创建了新的副线程

MessageBox( NULL, "已经创建了新的副线程、\n"

" 按确定结束主线程!", "主线程信息显示 __CopyRight - `海风 ", MB_OK | MB_TOPMOST );

ExitProcess(0);

return NULL;

}

如果说消息队列只有一个(在一个线程内),那么消息队列可以容纳多少条消息呢?我编程序去验证了一下:

// File Name: WinMain.cpp

#define WIN32_LEAN_AND_MEAN // Say No to MFC !!

#include <windows.h>

char Temp[77]="Hello world";

// Name: WinMain()

// ------ ---------- ----------- ---------

int WINAPI WinMain( HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine, int nCmdShow )

{

MessageBox( NULL, "按确定开始测试", "Simple_Code __CopyRight - `海风 ", MB_OK | MB_TOPMOST );

// 以上的一句请使用 Win98 的朋友别删除,因为在调用过创建窗口之类的函数后,你的线程才具有消息队列!

DWORD CurThreadID = GetCurrentThreadId( ); // 取得当前线程的 ID (标识号)

long i = 1 ;

for ( i = 1; i < 900000; i++)

{

if (! PostThreadMessage( CurThreadID, WM_USER , 11, 22 ) ) break;

// 上面的一句是如果不能再添加消息就打断 for 循环

}

wsprintf (Temp, "具体的消息队列长度是 %ld ", i);

MessageBox( NULL, Temp, "Sample_Code __CopyRight - `海风 ", MB_OK | MB_TOPMOST );

ExitProcess(0);

return NULL;

}

显示的结果是: 10000 ,有那么大么?!我也有点不太相信。

如果 10000 都还不够用,那么会怎样? 哎,当然是丢失了!

为了证明 消息队列 是 线程 的附属品,我查看了 MSDN ,最后在 PostThreadMessage() 函数的第一个参数解释那里找到证据,原文如下:

" The function fails if the specified thread does not have a message queue. The system creates a thread's message queue when the thread makes its first call to one of the Win32 User or GDI functions. For more information, see the Remarks section. "

含义大概是,当一个线程里面第一次调用 Win32 User 类函数 (或 图形界面类 函数) 的时候,系统会为该线程创建一个消息队列,否则就没有 消息队列。

不过,这个说法我认为在 Win2000 里面是不适用的,其实在系统创建线程的同时就创建了一个相关消息队列 (默认操作)。

我尝试过没有调用任何其他函数的情况下也可以成功发送 消息 到 队列。

这个由系统维护的消息队列也挺自动化的! 举个简单例子是系统会自动调整 WM_PAINT 消息的数量使之不会重复; 更复杂一点的例子是你向线程里的一个窗口发送消息,然后 Destroy 那个窗口,最后才检测消息队列。 系统会认为那个窗口已经不存在而将与那窗口相关的多余消息一并 删除掉了,所以你一定没法在消息队列里找到先前你发送的那条消息。

好了,说太多怕打乱你的思路了,详细资料请参看 MSDN . 请在 MSDN 的索引一栏输入 " message queues [Win32] "

下次有时间我会详细说明一下消息泵这玩艺! `海风 2002年10月12日 pm 2:28

——————————————————————————

附 Temp77 来历:

人生于世上匆匆,不过相当一个临时变量,因为我出生于 77 年,所以取名 Temp77 !

目前喜欢的歌: 久保田利伸 - Never Turn Back

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有