CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

俺没玩过多线程,高手指点需要注意的地方?

楼主lindamis(林子)2006-04-05 21:54:08 在 Delphi / VCL组件开发及应用 提问

我正在做关于多线程下载方面的东东,以前没有做过多线程,所以没有经验,请高手指点一下  
   
  我用了个AdvStringGrid用于指示当前下载的文件相关信息.  
  包括文件名,大小,和本地文件对比是否需要更新,下载速度,以及哪个线程在下载这个文件.  
   
  在线程中,首先查找没有下载的文件,我用了一个可变数组,其基类型是指向记录类型的指针  
  找到后开始下载,在下载过程中显示进步.  
   
   
   
  有以下几个方面感到迷域.  
   
  比如说,   在主程序中,有一停止按钮,用来停止所有线程.  
  具体办法是将一个全局逻辑型变量abortthread设为真时停止线程.  
  我在线程里用Synchronize(取abortthread值到一个临时变量里),再检查这个临时变量的值  
  这样做发现很影响下载速度.后来通过看书,在主程序中用threadvar来说明abortthread的类型.  
   
  我的问题是:这个全局变量的存取是否必须在Synchroniz()中,或其他同步或临界区等方法中.  
  能不能直接对这个全局变量的存取.  
   
  高手能否总结哪些是线程安全的?   即在线程中能直接存取.    
   
   
  关于threadvar,这个具体用在什么时候,用这个说明变量,是否就可以直接存取了.  
   
   
  多个线程下载时,需要显示下载速度.这时需要对AdvStringGrid中的CELL进行操作.这时也必须在  
  Synchroniz()中,或进入临界区等方法.  
  这样的操作,也会影响线程的执行速度!  
   
  我后来改用了自定义消息,但传到主线程中处理时,我给MSG的两个参数,赋给的是一个指针.  
  postmessage后,想主线程处理这个消息时,这个指针所指向的内容已发生变化,结果在消息处理中显示下载状态是,是错误的.  
   
  看到书中指出来的   sendmessage须等待消息处理完,再执行后面的.  
  所以不想用这个,主要想提高一下速度.    
   
  再在网上查,看到用内存映射文件,完成进程之间的通讯.但没有深看  
   
  高手们,有指点一下,你们是如何处理多线程这些地方的.  
   
  不用同步,出现一些内存共享冲突,头都大了,但全用同步,发现速度降了很多.  
   
   
  说的有点乱,望谅解.我困在这里很久了.  
   
  本贴我还会修改的,现在仓促一些,有空再修改一下.! 问题点数:100、回复次数:22Top

1 楼aiirii(ari-http://spaces.msn.com/members/aiirii/)回复于 2006-04-05 23:28:48 得分 5

>>我的问题是:这个全局变量的存取是否必须在Synchroniz()中,或其他同步或临界区等方法中.  
  能不能直接对这个全局变量的存取.  
   
  用   同步信号,或   临界区   是更好的解决方法  
  不要用   全局变量  
   
  >>关于threadvar  
   
  >>看到书中指出来的   sendmessage须等待消息处理完,再执行后面的.  
  PostThreadMEessageTop

2 楼ZyxIp(绝望中...)回复于 2006-04-06 00:58:55 得分 10

<WINDOWS核心编程>一书仔细看看.  
   
  将所有的线程保存到一个列表中,停止时分别调用每个线程的STOP方法.  
   
  多个线程之间应尽量少的交互.  
   
  和主窗体界面的交互用POSTMESSAGE消息的方式.  
   
  最重要的是要将你的工作逻辑分清楚,主要要从设计上避免性能的下降.Top

3 楼clasj(★知我☆)回复于 2006-04-06 11:03:49 得分 0

学习Top

4 楼happyct(绿叶对大树的情怀)回复于 2006-04-06 11:42:22 得分 5

其实,下载程序的速度瓶颈是在数据的存储。(网络没有限速的情况下)  
  用共享内存是可以解决问题,如果不是很熟悉的话,那么你可以考虑分段下载,分段存储,都下载完后,再合并Top

5 楼maxtool(≮From NingBoo≯)回复于 2006-04-06 14:22:37 得分 0

进来学习~~~Top

6 楼solokey(争取在2008年成为低级程序员)回复于 2006-04-06 21:47:32 得分 20

windows核心编程+win32多线程程序设计  
  都看一看..这2本书都是有电子版的.Top

7 楼lindamis(林子)回复于 2006-04-06 23:07:51 得分 0

感谢楼上的,该需要恶补的时候了,我在网上找到了这两本书windows核心编程+win32多线程程序设计  
  好好学习一下~~~~~~~~Top

8 楼coreblood(I don't Know )回复于 2006-04-06 23:10:43 得分 0

学习Top

9 楼linzhengqun(风。我回来了)回复于 2006-04-07 09:14:13 得分 20

也可参考这里面的线程杂谈:  
  blog.csdn.net/linzhengqunTop

10 楼lindamis(林子)回复于 2006-04-07 18:57:41 得分 0

感谢楼上的,linzhengqun(风。我回来了)   ,我已经保存了相关网页Top

11 楼YaYiYaO()回复于 2006-04-08 10:27:36 得分 40

1、线程的同步最好不要用Synchronize,很影响数据(Synchronize的真实面目是用主线程去执行相关的内容,这样还影响对用户操作的响应),最好用“互斥体”或“临界区”(EnterCriticalSection)。  
  2、结束线程不需要设全局变量,在线程类中设一个成员变量(比如:Fstoped:boolean),要停止的时候,主线程中用个循环将每个线程中的Fstoped置为真就好了  
  3、显示速度不需要同步(多线程中少用点同步,不然多线程的优势就体现不出来了),可以用窗体消息,速度改变时,线程向主窗体发个消息,窗体收到消息,改变AdvStringGrid中的内容  
   
  这些只是我的一些看法,不一定都对,大家相互学习学习,呵呵!!Top

12 楼YaYiYaO()回复于 2006-04-08 10:32:54 得分 0

不好意思,没看到下面你说的用postmessage  
  如果考虑速度用postmessage好,sendmessage要等待响应  
  postmessage不需要发指针地址,把线程和AdvStringGrid的行对应起来,发消息的时候只要发哪一行,什么速度就好了,这样肯定不会冲突Top

13 楼lindamis(林子)回复于 2006-04-09 17:25:44 得分 0

感谢YaYiYaO()!  
  针对你说的那几条,我把我的情况说一下  
  1、我原先是用TCriticalSection,在主程序中声明的。在线程中:  
   
  进入临界区   my_CriticalSection.enter  
  查找没有下载的文件  
  退出临界区   my_CriticalSection.leave  
   
  找到文件后  
  进入临界区   my_CriticalSection.enter  
  更新ADVSTRING   ,显示下载开始及线程编号  
  退出临界区   my_CriticalSection.leave  
   
  用FTP控件进行下载,在进度的事件中  
  进入临界区   my_CriticalSection.enter  
  更新ADVSTRING   ,显示当前下载速度  
  退出临界区   my_CriticalSection.leave  
   
  在下载结束后  
  进入临界区   my_CriticalSection.enter  
  更新ADVSTRING   ,显示下载完成  
  退出临界区   my_CriticalSection.leave  
   
  这样的架构中,发现有时某个线程,停止不动了,是不是死锁了。  
  后来改用Synchronize就没有出现过这样的问题。  
   
  是不是我有些地方没组织好  
   
  2、主线程可以直接对子线程中的变量直接读写,这点我确实不知道,我试试  
   
  3、关于postmessage,你说的是直接给AdvStringGrid这个控件发消息吗?  
        麻烦你真体说一下,我对消息和线程都是头一回使用。Top

14 楼YaYiYaO()回复于 2006-04-10 08:38:40 得分 0

1、如果使用消息更新AdvStringGrid,就不需要用到这么多的同步了,因为消息是采用队列形式的,至于为什么回停止,这里也看不出来  
  2、线程你应该是从TThread继承过来的一个类吧,你把变量放public中,主线程就可以随便访问了  
  3、你可以先自定义一个消息(如:MM_UPDATEGRID   =   WM_USER   +   110,WM_USER后为windows保留的用户自定义消息),消息只要发给放AdvStringGrid的窗体就ok了,然后在主窗体的类中定义一个函数用来处理这个消息(如:procedure   UpdateGrid(var   Message:TMessage);message   MM_UPDATEGRID;这里过程名称随便,参数名称也无所谓,但一定要加var,类型为tmessage,然后后面加message   MM_UPDATEGRID,MM_UPDATEGRID就是前面自定义的消息)  
   
  ps:处理自定义消息的方法有很多,我这里说的只是其中一种。如果觉得我这里说的不大清楚,你可以去找些例子看一下,应该还蛮简单的Top

15 楼shuihan20e(站的更高,尿的更远)回复于 2006-04-10 11:58:07 得分 0

我也来学习Top

16 楼lindamis(林子)回复于 2006-04-12 00:25:58 得分 0

YaYiYaO大师的指点,让我有点拔云见山,呵呵!!!  
   
  我改用发送消息,下载速度提高很多.(只差查找文件,还没改!),高兴~~~~~~~~~~  
   
  我用记录类型存放下载的文件相关数据,如,在grid中的行号,线程号,下载的速度等等...  
   
  在用   NEW(指向文件录的指针)申请地址后,将指针所指向的记录赋以文件相关数据  
  然后将这个指针作为POSTMESSAGE的参数,  
   
  在窗口程序的消息处理中,根据指针取出记录,更新ADVSTRINGGRID  
   
  再用DISPOSE释放指针所指向的内存  
   
  这样的做法是否正确?如果不释放,会不会造成内存泄漏?Top

17 楼YaYiYaO()回复于 2006-04-12 12:46:46 得分 0

理论上没什么问题,应该可行。自己多多调试吧,呵呵  
   
  ps:偶不是大师啦,第一次有人叫偶大师,hoho!!~~~  
  只是也做过些多线程方面的东东,对windows消息有那么一点点了解而已,大家相互学习学习Top

18 楼lindamis(林子)回复于 2006-04-16 22:28:49 得分 0

现在遇到的问题是发送的消息有可能丢失,我通过application.onmessage实现的.  
  如何确保发送的消息,百分百被处理?  
   
  另外我在主线程中,循环等待其他线程结束,在循环中,既要检测线程是否结束,并且还要处理线程发送的消息,为了降低CPU占用率,用msgwaitformultiobject是否合适.  
  请告诉其正确用法.或有什么其他更好的办法,使主线程所使用的CPU占用率最低Top

19 楼lindamis(林子)回复于 2006-04-17 23:24:33 得分 0

自己顶~~~~~~Top

20 楼lindamis(林子)回复于 2006-04-18 23:13:42 得分 0

自己顶~~~~~~  
  Top

21 楼YaYiYaO()回复于 2006-04-20 08:46:23 得分 0

要百分之百被处理的话就用sendmessage吧,但是这样影响速度,自己选择  
  但是我觉得这里消息只是通知主线程更改显示的内容,偶尔有几条数据收不到,应该没什么关系吧  
  至于“msgwaitformultiobject”,sorry,没用过Top

22 楼lmxlj(疯狂)回复于 2006-04-21 06:36:45 得分 0

为什么一定要用主线程呢,为什么不再另外启用一个线程呢,因为主线程有很多工作要做,所以不适合你说的对GRID进行操作.当然影响.Top

相关问题

关键词

得分解答快速导航

  • 帖主:lindamis
  • aiirii
  • ZyxIp
  • happyct
  • solokey
  • linzhengqun
  • YaYiYaO

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo