对vba实现多线程的解释说明。

对vba实现多线程的解释说明。vba 中可以调 windows api 函数实现多线程 但多线程其中的原理是什么呢 过程如何 或者说程序是如何运行起来的 函数是如何调用的 参数是如何传递的 网上很多文章说得过于专业了 让人读着费劲不知所云 本文用浅显的语言来解释说明下

欢迎大家来到IT世界,在知识的湖畔探索吧!

vba中可以调windows api 函数实现多线程。但多线程其中的原理是什么呢?过程如何?或者说程序是如何运行起来的,函数是如何调用的,参数是如何传递的?网上很多文章说得过于专业了,让人读着费劲不知所云。本文用浅显的语言来解释说明下。

本文的前提是:两个线程之间不共享数据,不涉及资源竟争,不考虑线程的同步协作等安全问题。

看下面的例子:

以下代码同时实现了两个任务:1,在word窗体顶上显示倒计时,一直不停地显示。2,出现对话框要求输入密码,不输入则word窗体永远锁定,无法使用。输入密码正确则进入word,可以使用。不正确则还允许输入三次,再不正确,则关闭word,不让用了。

Private Const INFINITE = &HFFFFFFFF

Private Declare Function WaitForSingleObject Lib “kernel32” _

(ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Declare Function CreateThread Lib “kernel32” _

(ByVal LpThreadAttributes As Long, _

ByVal DwStackSize As Long, _

ByVal LpStartAddress As Long, _

ByVal LpParameter As Long, _

ByVal dwCreationFlags As Long, _

ByRef LpThreadld As Long) As Long

Private Declare Function CloseHandle Lib “kernel32” _

(ByVal HANDLE As Long) As Long //以上声明api函数

Sub Main() //主线程

Dim x As Long //声明变量,放句柄

x=CreateThread(nil, 0, AddressOf secondary, nil, 0, nil) //创造线程,产生句柄


Application.AutomationSecurity =
msoAutomationSecurityForceDisable //强制启用宏,线程1开始运行

a = MsgBox(“必须先启用宏,否则无法使用word文档”, vbOKOnly, “快点”)

If a = vbOK Then

End If

Dim yyy As Date, www As Date

Dim so, t As Long

Do

yyy = Time

www = #9:25:00 PM#

so = Abs(DateDiff(“s”, yyy, www))

If so <= 0 Then

MsgBox “时间到!”

Exit Sub

End If

If so > 0 Then

hh = Round(so / 3600, 0)

mm = Int((so Mod 3600) / 60)

ss = Int((so Mod 3600) Mod 60)

ActiveWindow.Caption = “离解除密码的时间还有:” & hh & “小时” & mm & “分” & ss & “秒”

End If

t = Int(Timer)

Do While Int(Timer) = t

DoEvents

Loop

Loop //以上是倒计时代码,放主线程中

Call WaitForSingleObject(x, INFINITE) //等次线程结束

CloseHandle x //关闭句柄

End Sub //主线程结束

Sub secondary() //次线程

Dim wordapp As Word.Application

Dim closebl As Boolean, Document As Word.Document

Dim strPassword As String

On Error Resume Next

Set wordapp = GetObject(, “word.application”)

Dim i As Integer

If Err.Number <> 0 Then

Set wordapp = CreateObject(“word.application”)

closebl = True

End If

Set Document = wordapp.ActiveDocument

Do

strPassword = InputBox(“请输入密码”)

If strPassword = “” Then

MsgBox “密码正确,将进入word文档”

Exit Do

Exit Sub

ThisDocument.Activate

Else

MsgBox “密码有误,重新输入,不能超过三次”, vbCritical + vbInformation, “错误”

End If

i = i + 1

Loop While i <= 3

If i > 3 Then

MsgBox “已超过三次了,没机会了”, vbInformation, “将要退出WORD文档”

ThisDocument.Close

ActiveDocument.Visible = False

End If

DoEvents //以上是输入密码过程

End Sub //次线程结束

演示效果:

视频加载中…

什么是进程?

进程是操作系统分配资源的最小单元,最基本单位,是处于动态条件下由操作系统维护的系统资源管理实体。每个进程都拥有自己的内存空间,与其他进程区别,不进行内存共享。如浏览器就是一个进程。

什么是线程?

线程是操作系统调度执行的最小单元,最基本单位,是程序执行路径,是动态的概念。每个线程都拥有自己的寄存器、栈和计数器。如在浏览器中边下载电影边看网页上的新闻。

二者关系如何?

进程是包含线程的,每个进程至少有一个线程的存在,也就是主线程;一个进程如果只有一条执行路径,则称为单线程程序;一个进程如果有多条执行路径,则称为多线程程序。线程不能单独运行,必须依赖进程的资源。多个线程可以在同一个进程内同时并发执行,共享进程的资源。

多线程运行过程是怎么样的?

(1)首先声明windows api函数,准备调用。

api函数是一段有特殊功能的代码,由windows封存着。声明即激活,把它从仓库取出注入到内存中准备运行。就是工具箱,里面有很多工具。比如要修车,事先要准备好气泵,千斤顶,四轮定位之类。

(2)设立一个主线程,用来生产出其他线程。

上述例子中,将其中的倒计时任务放在主线程中执行;调CreateThread函数创造出另一个线程。也可以在主线程中什么都不放,将两个任务放主线程外,产生两个次线程。

主线程不用干预,操作系统有调度算法,会自动为之分配栈,寄存器,优先级,ID等资源。

创造次线程主要用createthread函数。CreateThread(nil, 0, AddressOf secondary, nil, 0, nil)中,只有第三个参数最有用,它是次线程的在内存中的地址,或者说是指针。实际操作中写次线程的名字就行。第五个参数一般置为0,表示次线程立即执行而不是挂起。其他参数均可以设置为空。

createthread是api函数,是windows给我们的工具。就靠这个函数,可以做很多事情。经过它的雕琢打磨加工后,它会吐出一个骨头,叫句柄。我们可以用它来诱惑或者唆使操作系统为我们做事情。通俗地说,句柄就是火车票。我们花钱买了windows,windows就给我们这张票,通过这个凭证可以享受windows内核对象给我们的服务。其他的api函数,如上例中的WaitForSingleObject和CloseHandle,与此一样,调用时都会激活内核对象,从而方便我们通过线程内核对象操作处理线程。

内核对象是什么东西呢?教科书上的概念是:内核对象是系统提供的用户模式下代码与内核模式下代码进行交互的基本接口。这样的定义看得人头晕。其实其本质没这么玄乎,就是一段有特殊功能的代码,平时压在箱底,需要时可以拿出来用。就跟政府的各种应急处理预案一样,社会上发生什么事情(用户态),如自然灾害,公共卫生,安全事故,重大刑案等,政府都会编制好预案,明确责任主体,发生了立即启动应急机制(内核态)。所以内核对象好比是应急预案,不管我们要实现什么样的功能,windows都给我们一一对应事先定制好了,需要时直接调出来用就行。

(3)线程加载到内存中,操作系统为之分配好资源后,会以并发的方式执行(不管cpu有多少个核,总有线程在并发轮流执行)。windows有线程调度算法保证线程的优先级,采用时间片轮转法来实现并发执行。所谓并发,就是在一个时间段内,不管cpu有多少个核,总有线程在轮流交替执行。每个线程都有己的时间片,执行完了,就切换到另一个线程,切换的速度飞快,你一会儿我一会儿,嘎嘎快,所以看起来是同时执行。上述例子中,倒计时任务一直不停运行,而同时word则处理输入密码的环节,两个线程互不干涉内政和平共处,可以一直运行下去。就好比边做作业边听音乐,在极短的时间内,大脑只处理一个事情,手与耳朵轮流动作 ,间隔时间很短,所以好像是同时时进行。这就是并发,强调的是一个时间段内做多个事情,本质上仍然是串行。

只有多核Cpu才可以做到部分并行。

(4)担心主线程过早结束而影响到次任务的运行,于是,在主线程中使用WaitForSingleObject 函数来检查次线程的状态,并接收其信息。如果次线程运行结束,操作系统会通过线程句柄x通知WaitForSingleObject函数,让它对主线程有所为有所不为。本例中则是让主线程结束运行状态,下班回去睡觉。

(5) 所有的线程都结束了,卸甲归田。通过closehandle函数把线程句柄x还给操作系统,表示我不再使用该句柄,即不再操作线程了,让操作系统准备打扫战场。若在线程执行完之后,没有调用CloseHandle,不归还句柄,将会造成内核对象的泄露。整个进程结束退出后,操作系统会自动撤消内核对象,回收内存等资源。就好比你到大澡堂洗澡,洗完之后肯定要把手牌(句柄)还给前台,告诉别人你洗完要走了。澡堂会清理你使用的储物柜,毛巾,躺椅,托鞋之类,以便让别人好用。要不然占着茅坑不拉屎,澡堂将陷入一片混乱。

总之,多线程的原理其实很简单,主要依赖windows提供给我们的功能实现并发,多个线程轮流执行。由于不涉及数据通信及资源共享,所以不必考虑线程安全问题。

多个线程间的有序执行为毛叫同步呢?让人无法理解。最好是叫线程的和谐。你看嘛,和谐社会,大家都遵守规则,不抢不占,相互帮肋,相互协作 ,一切者井然有序。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/108232.html

(0)
上一篇 17分钟前
下一篇 2分钟前

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信