VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
楼主: tgy

[分享] 改良的多线程绘图演示程序,供初学多线程者学习(含源码)

  [复制链接]
 楼主| 发表于 2012-3-16 17:20:24 | 显示全部楼层
sunson 发表于 2012-3-16 17:17
肯定不能用doevents,要不能用doevents就好了,其实就是我写的一个http代理程序,用的是winsock控件,接收 ...

出错要看你的线程函数如何写了,肯定访问了不该访问的东西

点评

tgy
而不是在于你的线程函数有多少语句  发表于 2012-3-16 17:28
tgy
多线程涉及很多东西,例如线同步问题,这些都要解决好才会稳定.  发表于 2012-3-16 17:26
我那段代码里面,主要的就两条语句,一条接收,一条发送,两个winsock控件处理而已  发表于 2012-3-16 17:22
回复 支持 反对

使用道具 举报

发表于 2012-3-16 17:33:48 | 显示全部楼层
tgy 发表于 2012-3-16 17:20
出错要看你的线程函数如何写了,肯定访问了不该访问的东西

Public Sub RunThread1(ByVal Index As Long, ByVal p2 As Long, ByVal p3 As Long, ByVal p4 As Long)
   Dim lErrNo As Long
'    Dim strDataReceived As String
    Dim bData() As Byte
    EnterCriticalSection gsect
    Form1.outsocket(Index).GetData bData, vbByte + vbArray
    Err.Clear
    Form1.insocket(Index).SendData bData
    lErrNo = Err
    If lErrNo <> 0 Then addLog Index & " outsocket_DataArrival " & lErrNo & " " & Err.Description, 0
    If lErrNo = 40006 Then
       Form1.outsocket(Index).Close
    End If
    LeaveCriticalSection gsect
End Sub

这段代码有问题吗?

点评

tgy
只能整体调试才能发现问题  发表于 2012-3-16 18:01
回复 支持 反对

使用道具 举报

发表于 2012-3-16 17:43:25 | 显示全部楼层
我发现调用你这个多线程DLL后,app对象就没法用,一用程序就挂了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-3-16 17:49:20 | 显示全部楼层
sunson 发表于 2012-3-16 17:43
我发现调用你这个多线程DLL后,app对象就没法用,一用程序就挂了

在主线程中先访问app一次,在新线程中就能访问APP对象了
比如在main()中第一句加上app.title=app.title
回复 支持 反对

使用道具 举报

发表于 2012-3-29 13:02:15 | 显示全部楼层
本帖最后由 bjtiantang 于 2012-3-29 13:04 编辑

这样的多线程,包括老汉的那个都有一个致命的bug,虽然通过vb6中一的一个函数可以使多线程内使用vb中好多函数不会崩溃,但是有一个严重的问题,每创建一个线程时,程序中 模块中的所有“全局变量”都会新申请一次内存占用,假设你的全局变量很多,那么每创建一个线程 内存都会不断的彪升,不信你自己试试,其实我发现了一个在线程使用VB 函数不崩溃的方法,将函数编译成activex.dll 然后用线程内对象调用,这样就不会崩溃了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-3-30 12:58:22 | 显示全部楼层
本帖最后由 tgy 于 2012-3-30 13:13 编辑
bjtiantang 发表于 2012-3-29 13:02
这样的多线程,包括老汉的那个都有一个致命的bug,虽然通过vb6中一的一个函数可以使多线程内使用vb中好多函数 ...


不知所说的新申请一次内存占用,是什么意思,但问题是全局变量还仍然是全局变量啊,另外创建线程肯定要占用内存的,最基本的线程堆栈都要内存,还有些共享的全局变量和对象.不然线程就不能访问这些对象和变量了
回复 支持 反对

使用道具 举报

发表于 2012-3-31 09:52:07 | 显示全部楼层
本帖最后由 bjtiantang 于 2012-3-31 10:07 编辑

回楼主,
同你所说, 每当创建一个线程,是需要占内存的,这个我同意,但是这个内存应该是过程内堆栈的内存,全局变量只需要线程内去访问,而不需要让他在线程内创建一个内存空间,而你这个多线程包括那个第x季 在创建一个线程后,就会把所有全局变量所占的内存,从新在线程内申请一份空间,但原变量值不改变,线程过程完成后才会释放这份空间,就象程序又从新运行了一次,但没有触发任何过程,因为你已经在启动中加入了sub main 加入了判断,所以并有触发任何过程 但是全局的内存变量又从新占了一边,直到线程完毕,难道其他语言创建线程也这样么? 请看下面用的改的范例,假设我的全面变量内存占用是100M 那么我同时创建100个线程同时运行,那么这个程序就会崩溃了,说明这样是错误的
看范例


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-3-31 16:18:58 | 显示全部楼层
本帖最后由 tgy 于 2012-3-31 17:05 编辑
bjtiantang 发表于 2012-3-31 09:52
回楼主,
同你所说, 每当创建一个线程,是需要占内存的,这个我同意,但是这个内存应该是过程内堆栈的内存,全 ...


这确实是个问题,以前都没有定义过很大的全局变量,所以没注意这个问题,但线程要访问全局变量,似乎也只能这样了。希望大家想办法解决。
不知是不是VB线程存储惹的祸。
发现一个临时解决方案:“尽可能不要把内存占用大的语句放到全局中,这样可以使用内存的申请可以控制”,不要直接定义静态数组,用动态数组,再从sub main中适当位置redim可暂时解决内存占用高的问题。
另,其实线程申请的那部分变量的内存根本就没有使用,实际使用的只是主线程中申请的那块。所以线程中申请的这部分内存是浪费了

如:

public a() as string

Sub Main()
    If frm_main.Visible = False Then frm_main.Show
    ReDim a(999999)
    App.TaskVisible = True
End Sub

点评

估计是你调用的那个函数有副作用,应该还要patch一下msvbvm60内部的东西  发表于 2012-3-31 22:39
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-4-2 14:04:07 | 显示全部楼层
本帖最后由 tgy 于 2012-4-2 19:56 编辑
bjtiantang 发表于 2012-3-31 09:52
回楼主,
同你所说, 每当创建一个线程,是需要占内存的,这个我同意,但是这个内存应该是过程内堆栈的内存,全 ...


这个不会重新申请全局变量占用的内存,当然也不会重入一次main,但存在其它一些问题:
1、msgbox的标题变成了“错误”,虽然不影响使用。
2、新线程不能创建新对象(也就是不能访问主线程存在的,但未实例化的对象),但可以访问主线程中已经实例化的对象。
其它未详细测试。
难道真是鱼与熊掌不可兼得?


补充内容 (2012-4-8 19:40):
这个对于一些场合还是适用的。只要不创建新对象,且不会重复执行main

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2012-4-29 23:32:06 | 显示全部楼层
本帖最后由 sunson 于 2012-4-29 23:33 编辑

tgy帮我看看附件里的测试程序,如何改成多线程的,我测试一下出错

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2022-7-3 16:12

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表