作者:梁利锋 标签:VB二三事, Thread

4914天前 (阅读:29521)
  昨天,网友的 Mail 中提到了 VB 多线程的问题:
  我这两天学人家编一些多线程程序,愣是咬着牙把Daniel Appleman的A Thread to Visual Basic文章读了不下五遍,结果就没看清楚他写的VB6下他的例程崩溃的那一段,结果即天以来,他的例程和我写的那些东西就是一次接一次的崩溃,后来我仔细看了那一段文字晕倒,正绝望间看到你写的多线程.vbp,顿时就像久旱逢甘霖般,高兴。
  不过还有几个问题想请教一下,麻烦指教:
  1.在调试过程中,退出示例时VB会崩溃,无论有没有按“结束新线程按钮。”
  2.这个示例稍显简单,没用线程进行到一定时候给主线程发送消息(或事件)的代码(VC++程序员真幸福),也没用线程同步,能不能给个更高级的示例?

  关于调试多线程程序,我认为是 VB 的问题,因为 VB 并没有想到人们会用 VB 来开发多线程的程序,调试就更不用说了。在调试过程中,VB 只是暂停了主线程,但是没有暂停子线程,所以子线程对主线程资源的访问将造成程序的崩溃。

  目前暂时没有精力写更高级的示例,不过我个人有几条原则,简单说一下:

  如果能用单线程实现,就用单线程(就我所开发的程序而言,目前还没有发现必须要用多线程实现的)。如果需要用多线程,可能的话,使用支持多线程调试的语言,比如 VC。如果对 VC 不熟,建议使用 VB.NET,其中已经内置了多线程编程的类,还有相关的例子,是一个比较好的选择。

  如果因为条件限制,必须用 VB5/6 编程,而又必须用多线程,建议将其拆分成多个工程,先将单线程调试通过,然后再将多个单线程组合成多线程的程序。

  另外,我的例子程序中没有使用线程同步代码,不过对于即使最简单的多线程程序,也应该进行线程同步,关于这一方面,可以参阅 Jeffrey Richter 的《Windows 核心编程》之中的第8、9章的介绍,当然,其中的程序是 C 语言的,不过也是可以很容易得改成 VB 的。

  不过,即使进行了线程同步,也未见得可以使用 VB 进行调试(不过确实有这种可能性),所以可能需要使用输出log文件的方式进行调试吧。

  相关文档:
   我写的VB多线程的例子程序(老的例子)
   点睛 VB5 多线程示例 第三版

后续问题 (梁利锋)
  最近,又在 VB6sp5 上测试编译有同步代码的例子程序,同样的是出错退出,经过检测,只要在新线程中调用 EnterCriticalSection、LeaveCriticalSection 的话,就会出错,本来怀疑,是否 vb6 中 Declare 语句造成,所以用 C 编写了一个 DLL ThreadHelper,去执行以上的函数,还是出错,而用 C 链接那个 DLL 的话,一切正常。另外,如果由 C 创建新线程,在线程函数中回调 VB 的线程函数,在 VB 的线程函数中调用 EnterCriticalSection 等函数仍然出错;而在 C 的线程函数中调用 EnterCriticalSection 等函数后再回调 VB 的线程函数就没有问题。烦死了。所以,如果要用 CriticalSection 族同步函数的话,请使用 vb5,或者在 vb6 中只使用原子访问方式的同步代码…… 另外,更方便的方法当然是:如果喜欢 vb 的语法,使用 vb.net,只要用 lock 就可以进行线程同步;如果也可以使用 C 的话,主线程仍然可以用 vb6,而子线程函数就用 C 写成 DLL 吧。


行星(非注册用户) 2004-3-19 16:33:34

你好,这个程序我试过了,最后能运行,但是关闭程序时提示:“"0x0fa9174b"指令引用的"0x03baff60"内存。该内存不能为"read"。”是不是进程无法结束而推出程序导致的错误呢?谢谢!

梁利锋 2004-3-22 20:18:51

我的测试,不论VB5还是VB6(SP5)编译,这个例子都是正常的。是否你的系统已经有些乱了?

deer(非注册用户) 2004-4-20 3:04:06

这样的例子是没问题,但是我想问一下,对于这种多线程编程,怎么解决OCX控件的访问?比如我在线程中访问主进程的MSFlexGrid控件?按这样的代码肯定是要出错的

梁利锋 2004-4-20 20:01:12

加入了线程同步代码后,因该无论使用标准控件,还是使用ActiveX控件,都没有问题的。

齐(非注册用户) 2004-4-21 16:18:20

这个例子运行时是能占用100%的cpu,但是运行结束是就会推出vb了,不知道为什么

梁利锋 2004-4-21 20:47:49

我的测试,没有“运行结束是就会退出vb”的问题。

彭xxx(非注册用户) 2004-4-23 10:17:43

这是多线程吗?我总感觉就只是一个线程

梁利锋 2004-4-24 9:38:40

主线程加子线程,共两个线程。第三版有两个子线程,共三个线程。

xyg(非注册用户) 2004-5-25 10:27:57

到最后退出程序时,总是提示内存出错,(只读)。----初学者的疑惑

梁利锋 2004-5-25 20:41:20

VB的多线程程序不能在调试模式下运行,只能编译成EXE文件执行,另外,VB版本的不同似乎也会造成不同的结果……

小辛(非注册用户) 2004-6-18 11:26:17

我在生成exe是可一直运行不出来,请指教.
emil:xinbin_120@126.com

梁利锋 2004-6-19 9:40:20

生成exe运行不出来可能是VB版本不同造成的,建议分别用 vb5、vb6 以及各种 sp 版本测试生成结果看看。当然,这样很麻烦,远不如直接用 vb.net 方便了。

lyh(非注册用户) 2004-10-6 17:32:53

梁利锋你好把你的线程函数换成语句 Form1.Image1.Picture = LoadPicture(App.Path & "\a.jpg") 编译成exe文件后总是死机,是何原因?(vb6环境)

梁利锋 2004-10-6 21:09:52

vb6环境确实会造成死机,轻使用 vb5 环境编译。

陈晓东(非注册用户) 2004-11-5 15:25:52

我是VB6(SP5),但是也会在退出时退出VB!LYH的问题肯定会出错吧,线程里调用控件好像不行

YangQing(非注册用户) 2004-11-9 13:53:16

Good!

chinayu(非注册用户) 2006-3-10 0:19:48

第三版在vb6时,创建关闭线程都正常,退出时出错,而且只能再p-code方式编译
老例子可以编为本机代码,但是在线程函数中调用其他函数,打开正常,关闭线程,出错

王彩霞(非注册用户) 2007-6-24 11:17:42

我用VB做双串口的通信,(是一个测量系统)计算机通过一个串口控制器件运动,同时通过另一个串口读取测量数据!我想请问需不需要多线程?我只会VB,而且以前也没有接触过多线程 caixia336@sina.com

梁利锋 2007-6-24 13:28:36

to 王彩霞:
我个人认为不需要,只要用DoEvents应该就可以了,不过,也不一定,实际测试一下就知道了。

嗷嗷叫的老马(非注册用户) 2008-4-18 13:03:44

在VB6里面,可用ActiveX EXE加单元模型线程,达到多线程效果.
在ActiveX EXE中,使用CreateObject函数建立的对象将工作在另一单元中,宏观上,是另一个单独的线程.
但是,这种多线程实现,线程间的调度貌似开销很大(MSDN里说的),不过不失为一种折中的方案---至少它非常稳定.
具体的,可以到MSDN中搜索"单元模型线程",也可以GOOGLE"VB 稳定多线程"

Yang(非注册用户) 2008-12-1 10:26:19

老的版本在 VB6 上没有问题,新的有问题。

丹丹(非注册用户) 2009-5-12 16:12:04

有朋友知道:瞿伦川的联系方式吗? 
开户人:瞿伦川
卡号:6222 0231 0000 1025 712 点睛软件工作室 www.djcg.cn QQ:466489208 E_MAIL:dsxxqlc@yahoo.com.cn
如果有朋友知道请告诉我,因为我们已经给他付款,他却说没有,银行记录清清楚楚,我不明白作为一个生意人,怎么能这样。

梁利锋 2009-5-13 9:40:47

@丹丹:不好意思,完全没听说过瞿伦川这个人。另外,点睛工作室和他的“点睛软件工作室”也没有任何关系。

点睛软件工作室(非注册用户) 2009-6-13 0:10:13

丹丹你好.你联系QQ466489208就可以了.他们会给你核查汇款情况的

点睛软件工作室(非注册用户) 2009-6-13 0:28:17

点睛软件工作室www.djcg.cn的诚诺是__竭诚为您服务到永远!!所有关注和使用软件的客户请在购买前先试用软件并联系工作人员QQ466489208

Joseph(非注册用户) 2010-3-9 20:57:51

第三版运行结束后是异常退出哦?

XL(非注册用户) 2010-3-16 10:43:53

楼主 NB~

tsggsd8gngfduifvnd(非注册用户) 2010-12-12 14:52:49

fduasdfsdcvna

11111111(非注册用户) 2011-8-4 23:15:35

第3版的代码根本不能运行

Boom shalakkaa boom boom, problem solved.(非注册用户) 2012-10-23 4:41:17

Boom shalakkaa boom boom, problem solved.