游戏开发论坛

 找回密码
 立即注册
搜索
查看: 7711|回复: 23

纠正几个概念

[复制链接]

14

主题

163

帖子

178

积分

注册会员

Rank: 2

积分
178
QQ
发表于 2006-2-21 16:48:00 | 显示全部楼层 |阅读模式
系统Timer ------- Windows定时器,没有专门的堆栈,一个时间片激活只有一个循环,这种请大家不要再说成线程(原因见:操作系统理论)
数组 ----- 不是要故意的贬低游戏之家,游戏之家早期的作品很多地方可以不用一个一个的写,数组就可以做到.

另外,只要你没有2个以上的CPU,即使是多线程也不是一个时间内运行两个程序,而是时间片的分配问题(原因见:操作系统理论)

好了就说这些,大家应该能分清楚他们了. [em13]

最新的解释图:

10

主题

96

帖子

96

积分

注册会员

Rank: 2

积分
96
发表于 2006-2-21 17:05:00 | 显示全部楼层

Re:纠正几个概念

那多线程是什么意思

14

主题

163

帖子

178

积分

注册会员

Rank: 2

积分
178
QQ
 楼主| 发表于 2006-2-21 17:07:00 | 显示全部楼层

Re:纠正几个概念

多线程1)有专门的时间片
          (2)要有专用的堆栈
          (3)能和进程一样调度

89

主题

4036

帖子

4132

积分

论坛元老

Rank: 8Rank: 8

积分
4132
发表于 2006-2-21 23:22:00 | 显示全部楼层

Re:纠正几个概念

线程的切换和进程是很有区别的。线程的切换不会引起任务的切换,操作系统不需要保存一大堆的TSR信息。
所以切换起来比较快。
而进程切换的开销是很大的。

所以操作系统提供了线程,线程是有自己的时间片的。两个线程可以并发执行(注意我说的并发,完全是可以是同时执行的,比如在双核心的CPU,多CPU上,他们在物理上就可以完全独立的运行的)

14

主题

163

帖子

178

积分

注册会员

Rank: 2

积分
178
QQ
 楼主| 发表于 2006-2-22 19:58:00 | 显示全部楼层

Re:纠正几个概念

1.线程的切换就是进程的切换,至少Linux是这样做的,线程在Linux内核里叫轻量级进程,以后的线程也是基于这个做的
2.所以操作系统提供了线程,线程是有自己的时间片的。两个线程可以并发执行(注意我说的并发,完全是可以是同时执行的,比如在双核心的CPU,多CPU上,他们在物理上就可以完全独立的运行的)           -----------没看见我写的吗,我只是说单核心的CPU是不能并发运行的.
3.线程也有TSR,但比进程少就是了,劝你仔细看看Linux内核.

7

主题

229

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
QQ
发表于 2006-2-23 13:58:00 | 显示全部楼层

Re:纠正几个概念


可能大家对于windows计时器和进程及线程的概念还不是很清晰,那么我将帮大家详细的解释一下它们的区别:

一、进程和线程:

windows操作系统是如何管理所有正在运行的应用程序?什么是进程?以及操作系统如何创建进程内核对象,以便管理每个进程?……

进程的定义:进程通常被定义为一个正在运行的程序的实例,它由两个部分组成:

1)一个是操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方。

2)另一个是地址空间,它包含所有可执行模块或D L L 模块的代码和数据。它还包含动态内存分配的空间。如线程堆栈和堆分配空间(32位的windows操作系统为每个PE即EXE分配高达4GB的虚拟地址空间,而我们可用的仅为2GB或是3GB左右)。


图4-1 操作系统在单个CPU 计算机上用循环方式为各个线程提供时间片

进程是不活泼的。若要使进程完成某项操作,它必须拥有一个在它的环境中运行的线程,该线程负责执行包含在进程的地址空间中的代码。实际上, 单个进程可能包含若干个线程,所有这些线程都“同时”执行进程地址空间中的代码。为此,每个线程都有它自己的一组CPU 寄存器和它自己的堆 栈。每个进程至少拥有一个线程,来执行进程的地址空间中的代码。如果没有线程来执行进程的地址空间中的代码,那么进程就没有存在的理由了,系统就将自动撤消该进程和它的地址空间。

若要使所有这些线程都能运行,操作系统就要为每个线程安排一定的C P U 时间。它通过以一种循环方式为线程提供时间片(称为量程),造成一种 假象,仿佛所有线程都是同时运行的一样。图4 - 1显示了在单个CPU的计算机上是如何实现这种运行方式的。如果计算机拥有多个CPU ,那么操作系统就要使用复杂得多的算法来实现CPU上线程负载的平衡。

当创建一个进程时,系统会自动创建它的第一个线程,称为主线程。然后,该线程可以创建其他的线程,而这些线程又能创建更多的线程。

Windows 2000: Micorsoft Windows 2000能够在拥有多个CPU 的计算机上运行。Windows 2000可以在每个CPU上运行不同的线程,这样,多个线程就真的在同时运行了。Windows 2000的内核能够在这种类型的系统上进行所有线程的管理和调度。不必在代码中进行任何特定的设置就能利用多处理器提供的各种优点。

Windows 98: Windows 98 只能在单处理器计算机上运行。即使计算机配有多个处理器,Windows每次只能安排一个线程运行,而其他的处理器则处于空闲状态。

通常情况下,一个应用程序拥有一个用户界面线程,用于创建所有窗口,并且有一个G e t M e s s a g e循环。进程中的所有其他线程都是工作线程,它们与计算机或I / O相关联,但是这些线程从不创建窗口。另外,一个用户界面线程通常拥有比工作线程更高的优先级,因此用户界面负责向用户作出响应。

虽然单个进程拥有多个用户界面线程的情况并不多见,但是这种情况有着某种有效的用途。Windows Explorer为每个文件夹窗口创建了一个独立的线程。它使你能够将文件从一个文件夹拷贝到另一个文件夹,并且仍然可以查看你的系统上的其他文件夹。另外,如果E x p l o r e r中存在一个错误,那么负责处理文件夹的线程可能崩溃,但是仍然能够对其他文件夹进行操作,至少在执行的操作导致其他文件夹也崩溃之前,仍然可以对它们进行操作(关于线程和用户界面的详细说明,参见第2 6和2 7章)。

上述内容的实质是应该慎重地使用多线程。不要想用就用。仅仅使用赋予进程的主线程,就能够编写出许多非常有用的和功能强大的应用程序。


二、windows计时器:


1、功能和概述:

Microsoft Windows计时器是一种输入设备,它周期性地在每经过一个指定的时间间隔后就通知应用程序一次。您的程序将时间间隔告诉Windows,例如「每10秒钟通知我一声」,然后Windows给您的程序发送周期性发生的WM_TIMER消息以表示时间到了。

初看之下,Windows计时器似乎不如键盘和鼠标设备重要,而且对许多应用程序来说确实如此。但是,计时器比您可能认为的要重要得多,它不只用于计时程序,比如出现在桌面上最下端的工具条中的Windows时钟。下面是Windows计时器的其他应用,有些可能并不那么明显:

1)多工:虽然Windows 98是一个优先权式的多工环境,但有时候如果程序尽快将控制传回给Windows效率会更高。如果一个程序必须进行大量的处理,那么它可以将作业分成小块,每接收到一个WM_TIMER消息处理一块。
 
2)维护更新过的状态报告:程序可以利用计时器来显示持续变化屏幕的「即时」更新,比如关于系统资源的变化或某个任务的进展情况。
 
3)实现「自动储存」功能:计时器提示Windows程序在指定的时间过去后把使用者的工作储存到硬盘中。
 
4)终止程序显示版本的执行:一些程序的显示版本被设计成在其开始后,多长时间结束,比如说,30分钟。如果时间已到,那么计时器就会通知应用程序。
 
5)步进移动:游戏中的图形物件或电脑辅助教学程序中的连续显示,需要按指定的速率来处理。利用计时器可以消除由于微处理器速度不同而造成的不一致。
 
6)多媒体:播放CD声音、声音或音乐的程序通常在背景播放声音资料。一个程序可以使用计时器来周期性地检查已播放了多少声音资料,并据此协调萤幕上的视觉屏幕。
 
另一项应用可以保证程序在退出窗口消息处理程序后,能够重新得到控制。在大多数时情况下,程序不能够知道何时下一个消息会到来。

2、计时器入门:
 

您可以通过调用SetTimer函数为您的Windows程序分配一个计时器。SetTimer有一个时间间隔范围为1毫秒到4,294,967,295毫秒(将近50天)的整数型态参数,这个值指示Windows每隔多久时间给您的程序发送WM_TIMER消息。例如,如果间隔为1000毫秒,那么Windows将每秒给程序发送一个WM_TIMER消息。当您的程序用完计时器时,它调用KillTimer函数来停止计时器消息。在处理WM_TIMER消息时,您可以通过调用KillTimer函数来编写一个「限用一次」的计时器。KillTimer调用清除消息队列中尚未被处理的WM_TIMER消息,从而使程序在调用KillTimer之后就不会再接收到WM_TIMER消息。

3、系统和计时器:

Windows计时器是PC硬件和ROM BIOS架构下之计时器一种相对简单的扩充。回到Windows以前的MS-DOS程序写作环境下,应用程序能够通过拦截者称为timer tick的BIOS中断来实现时钟或计时器。一些为MS-DOS编写的程序自己拦截这个硬件中断以实现时钟和计时器。这些中断每54.915毫秒产生一次,或者大约每秒18.2次。这是原始的IBM PC的微处理器时脉值4.772720 MHz被218所除而得出的结果。

Windows应用程序不拦截BIOS中断,相反地,Windows本身处理硬件中断,这样应用程序就不必进行处理。对于目前拥有计时器的每个程序,Windows储存一个每次硬件timer tick减少的计数。当这个计数减到0时,Windows在应用程序消息队列中放置一个WM_TIMER消息,并将计数重置为其最初值。

因为Windows应用程序从正常的消息队列中取得WM_TIMER消息,所以您的程序在进行其他处理时不必担心WM_TIMER消息会意外中断了程序。在这方面,计时器类似于键盘和鼠标。驱动程序处理非同步硬件中断事件,Windows把这些事件翻译为规律、结构化和顺序化的消息。

在Windows 98中,计时器与其下的PC计时器一样具有55毫秒的解析度。在Microsoft Windows NT中,计时器的解析度为10毫秒。

Windows应用程序不能以高于这些解析度的频率(在Windows 98下,每秒18.2次,在Windows NT下,每秒大约100次)接收WM_TIMER消息。在SetTimer调用中指定的时间间隔总是截尾后tick数的整数倍。例如,1000毫秒的间隔除以54.925毫秒,得到18.207个tick,截尾后是18个tick,它实际上是989毫秒。对每个小于55毫秒的间隔,每个tick都会产生一个WM_TIMER消息。

4、计时器消息不是非同步的:
 
因为计时器使用硬件计时器中断,程序写作者有时会误解,认为他们的程序会非同步地被中断来处理WM_TIMER消息。

然而,WM_TIMER消息并不是非同步的。WM_TIMER消息放在正常的消息队列之中,和其他消息排列在一起,因此,如果在SetTimer调用中指定间隔为1000毫秒,那么不能保证程序每1000毫秒或者989毫秒就会收到一个WM_TIMER消息。如果其他程序的执行事件超过一秒,在此期间内,您的程序将收不到任何WM_TIMER消息。事实上, Windows对WM_TIMER消息的处理非常类似于对WM_PAINT消息的处理,这两个消息都是低优先顺序的,程序只有在消息队列中没有其他消息时才接收它们。

WM_TIMER还在另一方面和WM_PAINT相似:Windows不能持续向消息队列中放入多个WM_TIMER消息,而是将多余的WM_TIMER消息组合成一个消息。因此,应用程序不会一次收到多个这样的消息,尽管可能在短时间内得到两个WM_TIMER消息。应用程序不能确定这种处理方式所导致的WM_TIMER消息「遗漏」的数目。

这样,WM_TIMER消息仅仅在需要更新时才提示程序,程序本身不能经由统计WM_TIMER消息的数目来计时。

但是请记住,这些消息并非精确的tick中断。


结论:由于VB产生的PE即EXE特殊(不同于cl.exe编译的PE,它需要msvbvmx0.dll的支持和操作系统打交道),故VB的应用程序只有一个主线程!无法再用CreateThread的函数在进程上创建其它的线程(即实现多线程)。但是,通过timer控件(windows计时器)的介入,通常也能完成一些关于多工方面的操作(目前的CPU够快,一些微妙的时间差别大家还是看不出来的),如果其它的消息没有影响到WM_TIMER的时间片的话。不过,windows计时器是居于主线程的消息队列的,所以,这种方式和常规的多线程是完全有区别的。

7

主题

229

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
QQ
发表于 2006-2-23 14:04:00 | 显示全部楼层

Re:纠正几个概念

参考资料:

1、《Windows程式设计》Charles Petzold
2、《Windows核心编程》Jeffrey Richter

7

主题

229

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
QQ
发表于 2006-2-23 14:05:00 | 显示全部楼层

Re:纠正几个概念

希望大家看看这两本书,对于WIN32的功力,将会倍增。

7

主题

229

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
QQ
发表于 2006-2-23 14:06:00 | 显示全部楼层

Re:纠正几个概念

骂人的话少一点,多一些技术讨论和交流。客观建议

64

主题

855

帖子

856

积分

高级会员

Rank: 4

积分
856
QQ
发表于 2006-2-23 14:34:00 | 显示全部楼层

Re:纠正几个概念

所谓Timer看上去象是多线程只是由于程序的当前执行时间比较短而已,如果该程序执行时间较长,就能明显看出:Timer中的程序必须等当前程序段结束才会被执行到。

所以可以总结:Timer中的程序被调用执行必须当当前进程正处于空闲状态才会被按时触发,否则有可能晚触发,甚至如果当前进程为阻塞状态,则Timer程序将永远不会执行。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-23 19:49

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表