我正在做关于多线程下载方面的东东,以前没有做过多线程,所以没有经验,请高手指点一下我用了个AdvStringGrid用于指示当前下载的文件相关信息.
包括文件名,大小,和本地文件对比是否需要更新,下载速度,以及哪个线程在下载这个文件.在线程中,首先查找没有下载的文件,我用了一个可变数组,其基类型是指向记录类型的指针
找到后开始下载,在下载过程中显示进步.有以下几个方面感到迷域.比如说, 在主程序中,有一停止按钮,用来停止所有线程.
具体办法是将一个全局逻辑型变量abortthread设为真时停止线程.
我在线程里用Synchronize(取abortthread值到一个临时变量里),再检查这个临时变量的值
这样做发现很影响下载速度.后来通过看书,在主程序中用threadvar来说明abortthread的类型.我的问题是:这个全局变量的存取是否必须在Synchroniz()中,或其他同步或临界区等方法中.
能不能直接对这个全局变量的存取.高手能否总结哪些是线程安全的? 即在线程中能直接存取.
关于threadvar,这个具体用在什么时候,用这个说明变量,是否就可以直接存取了.
多个线程下载时,需要显示下载速度.这时需要对AdvStringGrid中的CELL进行操作.这时也必须在
Synchroniz()中,或进入临界区等方法.
这样的操作,也会影响线程的执行速度!我后来改用了自定义消息,但传到主线程中处理时,我给MSG的两个参数,赋给的是一个指针.
postmessage后,想主线程处理这个消息时,这个指针所指向的内容已发生变化,结果在消息处理中显示下载状态是,是错误的.看到书中指出来的 sendmessage须等待消息处理完,再执行后面的.
所以不想用这个,主要想提高一下速度. 再在网上查,看到用内存映射文件,完成进程之间的通讯.但没有深看高手们,有指点一下,你们是如何处理多线程这些地方的.不用同步,出现一些内存共享冲突,头都大了,但全用同步,发现速度降了很多.
说的有点乱,望谅解.我困在这里很久了.本贴我还会修改的,现在仓促一些,有空再修改一下.!
包括文件名,大小,和本地文件对比是否需要更新,下载速度,以及哪个线程在下载这个文件.在线程中,首先查找没有下载的文件,我用了一个可变数组,其基类型是指向记录类型的指针
找到后开始下载,在下载过程中显示进步.有以下几个方面感到迷域.比如说, 在主程序中,有一停止按钮,用来停止所有线程.
具体办法是将一个全局逻辑型变量abortthread设为真时停止线程.
我在线程里用Synchronize(取abortthread值到一个临时变量里),再检查这个临时变量的值
这样做发现很影响下载速度.后来通过看书,在主程序中用threadvar来说明abortthread的类型.我的问题是:这个全局变量的存取是否必须在Synchroniz()中,或其他同步或临界区等方法中.
能不能直接对这个全局变量的存取.高手能否总结哪些是线程安全的? 即在线程中能直接存取.
关于threadvar,这个具体用在什么时候,用这个说明变量,是否就可以直接存取了.
多个线程下载时,需要显示下载速度.这时需要对AdvStringGrid中的CELL进行操作.这时也必须在
Synchroniz()中,或进入临界区等方法.
这样的操作,也会影响线程的执行速度!我后来改用了自定义消息,但传到主线程中处理时,我给MSG的两个参数,赋给的是一个指针.
postmessage后,想主线程处理这个消息时,这个指针所指向的内容已发生变化,结果在消息处理中显示下载状态是,是错误的.看到书中指出来的 sendmessage须等待消息处理完,再执行后面的.
所以不想用这个,主要想提高一下速度. 再在网上查,看到用内存映射文件,完成进程之间的通讯.但没有深看高手们,有指点一下,你们是如何处理多线程这些地方的.不用同步,出现一些内存共享冲突,头都大了,但全用同步,发现速度降了很多.
说的有点乱,望谅解.我困在这里很久了.本贴我还会修改的,现在仓促一些,有空再修改一下.!
能不能直接对这个全局变量的存取.用 同步信号,或 临界区 是更好的解决方法
不要用 全局变量>>关于threadvar>>看到书中指出来的 sendmessage须等待消息处理完,再执行后面的.
PostThreadMEessage
都看一看..这2本书都是有电子版的.
好好学习一下~~~~~~~~
blog.csdn.net/linzhengqun
2、结束线程不需要设全局变量,在线程类中设一个成员变量(比如:Fstoped:boolean),要停止的时候,主线程中用个循环将每个线程中的Fstoped置为真就好了
3、显示速度不需要同步(多线程中少用点同步,不然多线程的优势就体现不出来了),可以用窗体消息,速度改变时,线程向主窗体发个消息,窗体收到消息,改变AdvStringGrid中的内容这些只是我的一些看法,不一定都对,大家相互学习学习,呵呵!!
如果考虑速度用postmessage好,sendmessage要等待响应
postmessage不需要发指针地址,把线程和AdvStringGrid的行对应起来,发消息的时候只要发哪一行,什么速度就好了,这样肯定不会冲突
针对你说的那几条,我把我的情况说一下
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这个控件发消息吗?
麻烦你真体说一下,我对消息和线程都是头一回使用。
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:处理自定义消息的方法有很多,我这里说的只是其中一种。如果觉得我这里说的不大清楚,你可以去找些例子看一下,应该还蛮简单的
然后将这个指针作为POSTMESSAGE的参数,在窗口程序的消息处理中,根据指针取出记录,更新ADVSTRINGGRID再用DISPOSE释放指针所指向的内存这样的做法是否正确?如果不释放,会不会造成内存泄漏?
只是也做过些多线程方面的东东,对windows消息有那么一点点了解而已,大家相互学习学习
如何确保发送的消息,百分百被处理?另外我在主线程中,循环等待其他线程结束,在循环中,既要检测线程是否结束,并且还要处理线程发送的消息,为了降低CPU占用率,用msgwaitformultiobject是否合适.
请告诉其正确用法.或有什么其他更好的办法,使主线程所使用的CPU占用率最低
但是我觉得这里消息只是通知主线程更改显示的内容,偶尔有几条数据收不到,应该没什么关系吧
至于“msgwaitformultiobject”,sorry,没用过