首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • vb实现多线程的一个另类实现方案,会有问题么? [已结贴,结贴人:shakoe]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • shakoe
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 揭贴率:
    发表于:2008-06-24 09:45:54 楼主
    采用定时器起线程~~~具体就是做一个单独功能的定时器,定时时间很短(例子里设为1)作用就是调用下线程函数,然后就关闭自己定时器。代码如下


    Private Sub Form_Load()
    Timer1.Enabled = False
    timer1.Interval =1
    End Sub


    Private Sub Timer1_Timer()  '专门开线程的定时器,开了以后马上关闭自己
    call  newthread
    Timer1.Enabled = False
    End Sub

    Private Sub Command1_Click()
    Timer1.Enabled = true        '通过打开定时器开线程
    end sub

    Private Sub newthread()  '需要开的线程函数
    ...
    ...
    end sub
    50  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • CityBird
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 10:20:071楼 得分:0
    这种方式仍然是单线程,不能实现多线程。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Modest
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

      2

      3

    发表于:2008-06-24 10:21:282楼 得分:0
    不是不可以,但非常麻烦。

    看看这个能否帮助你:http://blog.csdn.net/Modest/archive/2008/05/08/2416967.aspx
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unsigned
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 3

      2

      5

    发表于:2008-06-24 10:23:323楼 得分:0
    楼主明显没有了解多线程的概念。

    在VB当中使用多线程最大的问题是内存的隔离。由于VB(特指VB6及以下版本)原始设计并没有考虑到多线程,所以其解释器当中的内存管理也没有做线程隔离,从而导致在使用如CreateThread之类创建线程后,无法正常使用。唯一可行的办法就是通过COM调用,来实现隔离,包括使用ActiveX Exe内建COM对象来实现等等。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • vbman2003
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 10:28:214楼 得分:0
    简单的方法就是用activeX.exe
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • shakoe
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 10:31:295楼 得分:0
    发表于:2008-06-24 10:20:071楼 得分:0
    这种方式仍然是单线程,不能实现多线程。


    为啥不是多线程呢,我调用完timer1,然后再调用timer1的时候,不管newthread()有没有执行完都会再起一个newthread()实例的。

    我只是觉得这种方法对于一些简单的应用可能是一个相当直接的解决方案。

    因为我已经在我的一个代码里通过这个方法实现了多线程,但是我担心可能带来一些问题。


    麻烦大家拓展下思维,不要根据经验来下结论。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unsigned
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 3

      2

      5

    发表于:2008-06-24 10:39:016楼 得分:20
    引用 5 楼 shakoe 的回复:
    发表于:2008-06-24 10:20:071楼 得分:0
    这种方式仍然是单线程,不能实现多线程。


    为啥不是多线程呢,我调用完timer1,然后再调用timer1的时候,不管newthread()有没有执行完都会再起一个newthread()实例的。

    我只是觉得这种方法对于一些简单的应用可能是一个相当直接的解决方案。

    因为我已经在我的一个代码里通过这个方法实现了多线程,但是我担心可能带来一些问题。


    麻烦大家拓展下思维,不要根据经验来下…

    创建线程所需要花费的时间并不大,所以没有必要使用Timer,或者在同一个线程(主线程)当中执行是在Command按下的消息,还是Timer消息并没有差别。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • yachong
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 11:01:407楼 得分:0
    楼主的还是单线程,你试试下面的程序能输出多个时间吗?
    Private Sub Form_Load()
    Timer1.Enabled = False
    Timer1.Interval = 1
    End Sub

    Private Sub Timer1_Timer()  '专门开线程的定时器,开了以后马上关闭自己
    Call newthread(Now)
    Timer1.Enabled = False
    End Sub

    Private Sub Command1_Click()
    Timer1.Enabled = True        '通过打开定时器开线程
    End Sub

    Private Sub newthread(ByVal s As String)  '需要开的线程函数
        Do While True
            Debug.Print s
        Loop
    End Sub
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unsigned
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 3

      2

      5

    发表于:2008-06-24 11:07:018楼 得分:0
    汗,没注意,楼主所谓的newthread,竟然是在Timer当中直接Call,看来真如我在三楼说的,楼主压根儿就没理解什么是多线程,或者说也没有理解Timer的工作机制。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • myjian
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

    发表于:2008-06-24 11:16:329楼 得分:10
    引用 5 楼 shakoe 的回复:
    发表于:2008-06-24 10:20:071楼 得分:0
    这种方式仍然是单线程,不能实现多线程。


    为啥不是多线程呢,我调用完timer1,然后再调用timer1的时候,不管newthread()有没有执行完都会再起一个newthread()实例的。

    我只是觉得这种方法对于一些简单的应用可能是一个相当直接的解决方案。

    因为我已经在我的一个代码里通过这个方法实现了多线程,但是我担心可能带来一些问题。


    麻烦大家拓展下思维,不要根据经验来下…


    //

    看来还没有明白多线程的概念,呵呵~~~~~~

    举个例子给你:)

    假设有一天你在写代码~~~~然后突然你后背痒痒了~~~~如果此时你停下写代码的工作,转而挠痒痒去,就是等于你直接在按钮里CALL那个newthread()~~

    在你没挠完痒痒前,你是没办法继续写代码的~~~~因为你只有两只手(newthread返回前,按钮过程不会返回).

    再假设,这个时候,如果你有一个保姆,你可以告诉她,"帮我挠痒痒,在后背坐标为X,Y的地方~~~"

    于是你就可以继续做你的工作;但本质上这并不是你自己完成的,而是由保姆(操作系统)来替你完成的.(TIMER本质上是系统的一个回调,你给了一个回调时间)

    就如你的代码.

    继续.

    再再假设,如果你此时多长了两只手,那么你就可以用那两只手挠痒痒,再用剩下的两只手写代码~~~~

    这样才是真正的多线程.....

    也许比喻不是很合适,但大概的意思是这样了,看看能否明白吧:)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • myjian
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

    发表于:2008-06-24 11:19:0610楼 得分:0
    引用 8 楼 unsigned 的回复:
    汗,没注意,楼主所谓的newthread,竟然是在Timer当中直接Call,看来真如我在三楼说的,楼主压根儿就没理解什么是多线程,或者说也没有理解Timer的工作机制。


    可怜的僵哥,晕了吧,哇哈哈哈哈哈哈哈哈哈哈
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • vansoft
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 11:20:2111楼 得分:0
    以我的智慧很难向楼主解释。

    留与后来人。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • shakoe
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 11:31:3112楼 得分:0
    是呀,

    简单的说我要实现的功能是

    在我调用newthread()那个函数后,不用关心他是否完成,让newthread()在后台运行,直接去下一条语句

    这就类似开一个线程了

    本来的逻辑如下
    ......
    .......
    call newthread
    call anothersub
    要走到call anothersub这步,必须等call newthread,newthread()这个函数走完。


    但是使用本帖的机制后,

    ......
    .......
    Timer1.Enabled = true  '通过定时器来起newthread()这个函数实例
    call anothersub
    走到call anothersub这步就步需要newthread()这个函数走完。

    是不是类似在主线程之外另外又开了个线程去做newthread(),这样的形式。

    而且同时能够多次调用newthread(),而不去考虑前一个newthread()是否完成。


    当然我也隐约觉得在使用定时器的时候,不能做到同一时间片上的开多线程,例如以下语句就可能只起一个newthread()函数实例
    Timer1.Enabled = true
    Timer1.Enabled = true
    而以下语句就能起2个实例
    Timer1.Enabled = true
    delay(1)  '延迟1秒
    Timer1.Enabled = true


    但是由于我目前的应用之间会有不少时间间隔所以这个问题还不敏感。


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • shakoe
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 11:34:1413楼 得分:0
    由于timer控件也是一个ActivX控件

    所以是不是在一些特定的应用里,可以利用timer实现一些多线程的功能
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • CityBird
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 11:46:3614楼 得分:0
    显然搂主对于多线程的概念还不是很清楚。

    如果newthread()是在一个独立的线程中运行的话,newthread()的运行情况应该是不会影响到VB主线程的运行的,但是实际上在newthread()返回之前主线程里的Timer1.Enabled = False 根本就不会运行,由此可见newthread()实际上还是在VB的主线程里运行,并没有产生新的线程。

    或许你会说在newthread()里使用Doevents语句后就可以在newthread()返回之前先运行Timer1.Enabled = False,但是实际上Doevents的作用是释放系统的控制权,正因为newthread()占用了VB的主线程,所以才需要释放以后才能执行Timer1.Enabled = False这个语句,由此也可以说明newthread()是在VB主线程里运行的,并没有建立新的线程。而Doevents只是改变了代码执行的优先级,在newthread()里面使用Doevents以后VB会优先执行其他代码,只有在空闲时才会执行newthread()里面的代码,如果有其他事件发生,VB会暂停执行newthread()里的代码,优先响应其他事件,等其他事件响应完成后再回来继续执行newthread()。

    所以这不是多线程
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • shakoe
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 11:56:5015楼 得分:0
    楼上的我代码的确是错了,在定时器里面,先关闭自己的Enabled 再调用newthread ()


    Private Sub Timer1_Timer()  '专门开线程的定时器,开了以后马上关闭自己
    Timer1.Enabled = False
    call  newthread
    End Sub


    我要实现的功能是调用完newthread ()后直接不等newthread ()走完就执行下一条语句,

    原来的代码
    ......
    .......
    call newthread
    call anothersub
    要走到call anothersub这步,必须等call newthread,newthread()这个函数走完。


    那么我要实现调用完newthread ()后直接不等newthread ()走完就执行下一条语句本来可以
    ......
    .......
    creatthread(newthread ,.....)
    call anothersub
    通过另外开一个线程来实现,但是vb6对creatthread()的支持不够,编译好执行会出错

    所以我用本帖的机制实现了这个需求
    .......
    Timer1.Enabled = true  '通过定时器来起newthread()这个函数实例
    call anothersub
    走到call anothersub这步就不需要newthread()这个函数走完。


    这是一个标准的多线程的逻辑,所以我希望开贴讨论的是这么做带来的问题,而不是这么做是不是多线程


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unsigned
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 3

      2

      5

    发表于:2008-06-24 12:34:4516楼 得分:0
    建议楼主还是看书吧,直接看不明白什么是多线程的话,就看看操作系统原理。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • shakoe
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 12:38:2417楼 得分:0
    发表于:2008-06-24 12:34:4516楼 得分:0
    建议楼主还是看书吧,直接看不明白什么是多线程的话,就看看操作系统原理。


    昏迷啊,只是用不同的方式看看如何解决问题。

    计算机是实践科学不是理论科学,只要能达到目的,无论怎么做都可以啊。

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • shakoe
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 12:40:4818楼 得分:0
    多线程么就是这么回事情,可以说vb6的一个定时器就是一个线程,

    我就是把自己的函数通过定时器简单的实现下多线程的机制,但是想知道会出现什么问题么

    难道都没人能理解这个问题么。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unsigned
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 3

      2

      5

    发表于:2008-06-24 12:50:4519楼 得分:0
    引用 18 楼 shakoe 的回复:
    多线程么就是这么回事情,可以说vb6的一个定时器就是一个线程,

    我就是把自己的函数通过定时器简单的实现下多线程的机制,但是想知道会出现什么问题么

    难道都没人能理解这个问题么。

    有谁告诉过你VB6的一个定时器就是一个线程?还是什么权威资料说明如此,还是你自己的想当然?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unsigned
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 3

      2

      5

    发表于:2008-06-24 12:53:3320楼 得分:0
    你可以说是一个通过消息机制进行任务的串行,但是并不能称之为多线程。这种串行,只能达到某一些特定的目的,但是并不能达到多线程的并行机制。对于消息的处理,当我现在有一个死循环在作业,并且没有任何消息处理(Call DoEvents),那么你什么Timer也交无济于事。但是线程却是相互独立。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • gzmaple
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 12:54:3421楼 得分:0
    我理解SHAKOE的意思.
    TIMER用起来确实可以隔绝其他代码的影响.TIMER在VB6的优先级是其他控件最高的.再加上上时间定时TIMER出现会出现一点偏差,跑不准了,所谓程序员老感觉TIMER耗资源的原因也就在于此.不过1楼的程序写得还是有点牵强.我觉得应该是把工作代码放到TIMER定时区间里干活,这样回避其他单线程代码对TIMER内代码的约束.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • CityBird
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 12:58:3622楼 得分:0
    猪头,我实在不想用这个词来称呼你,但是除了这个称呼外我实在想不出更恰当的。

    14楼的回复是试图向你说明VB的运行机制,并同时说明你的这个想法或逻辑或这种实现方式并不是一个多线程,而仍然是个单线程,而不是为了指出Timer1.enabled=false这句代码的位置问题。

    你原来的代码
    ......
    .......
    call newthread
    call anothersub
    是需要先执行newthread,等newthread完成返回后再执行anothersub

    你新的代码
    .......
    Timer1.Enabled = true  '通过定时器来起newthread()这个函数实例
    call anothersub
    是先执行anothersub,等anothersub完成返回后再过1个毫秒的时间再执行newthread。
    你认为在设置Timer1.enabled=true以后timer1就开始计时,1毫秒以后自动执行newthread,不用等到newthread返回你可以继续执行anothersub,newthread和anothersub可能会同时都在执行(anothersub执行时间超过1毫秒),但是实际上在执行Timer1.enabled=true以后Timer1并没有开始计时,而是等到Timer1.Enabled=true所在的这个过程或函数里面的所有代码都执行完成以后才会开始计时,再经过1毫秒的时间以后才会执行newthread里的内容。

    你的新代码和
    …………
    …………
    call anothersub
    call newthread
    这种发式的区别是浪费了1毫秒的等候时间!(call anothersub后面没有其他代码)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ayalicer
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-06-24 13:00:1723楼 得分:0
    只要能实现你的需求管它是不是多线程呢~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • myjian
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

    发表于:2008-06-24 13:54:3724楼 得分:10
    "在我调用newthread()那个函数后,不用关心他是否完成,让newthread()在后台运行,直接去下一条语句"

    //

    看看是下一条语句与TIMER事件里的一起执行了,还是顺序执行了?

    反正光说的话你可能听不进去~~~~

    那就直接用你的代码测试吧!!代码是你的,总没问题了吧~~~

    如果是多线程,两个MSGBOX理论上应该相隔1MS弹出来~~~

    VB code
    '窗体上添加一个TIMER,一个COMMANDBUTTON. Option Explicit Private Sub Form_Load() Timer1.Enabled = False Timer1.Interval = 1 End Sub Private Sub Timer1_Timer() '专门开线程的定时器,开了以后马上关闭自己 Call newthread Timer1.Enabled = False End Sub Private Sub Command1_Click() Timer1.Enabled = True '通过打开定时器开线程 Call newthread2 End Sub Private Sub newthread() '需要开的线程函数 Dim I As Long, J As String For I = 1 To 200000 J = J & "A" '字符串累加,很费时 Next I MsgBox "OK-1" End Sub Private Sub newthread2() '需要开的线程函数 Dim I As Long, J As String For I =