开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 8491|回复: 25
收起左侧

[分享] 浅谈多线程、许可区编程(从别地儿转来无意之中找到的)

[复制链接]

结帖率:100% (1/1)
发表于 2014-6-26 12:02:06 | 显示全部楼层 |阅读模式   河南省焦作市
浅谈多线程、许可区编程谈谈我自己对多线程上的理解,因本人知识有限,如有不对之处请各位高手多多指正、补充,同时,在多线程上有问题而不能解决的易友,可以将自己问题提出,并附上源码(不愿提供源码别找我,我不是神,无法猜测出问题所在),我将会一一测试,并在本人能力范围内解决:
一、简介
1、线程句柄与线程:
①、关闭线程句柄对线程的运行不会有影响,关闭句柄并不代表结束线程;
②、线程句柄是用于对线程挂起、恢复、结束等操作,线程创建后,都会有一个线程句柄,如果不需要对线程句柄进行操作,建议立即关闭线程句柄;
③、线程句柄必须在适当的时候关闭,否则会造成句柄泄露,但不同于内存泄露。
2、死锁、循环死锁、活锁
①、死锁:线程A占有资源A,线程B占有资源B,线程A申请占有资源B,同时要求占有资源B之后才释放资源A,而线程B申请占有资源A,同时要求占有资源A之后才释放资源B,这样两个线程互相永久等待对方释放资源,这就是死锁。
②、循环死锁:线程A占有资源A,线程B占有资源B,线程C占有资源C,线程A申请占有资源B,同时要求占有资源B之后才释放资源A,而线程B申请占有资源C,同时要求占有资源C之后才释放资源B,线程C申请占有资源A,同时要求占有资源A之后才释放资源C,这样线程互相永久等待对方释放资源,这就是循环死锁。
③、活锁:提交任务之后,任务永远处于等处理状态,这就是活锁。这种情况比较少见,但是出现这种情况,将比死锁更加不易查觉,避免活锁的简单方法是采用先来先处理。
二、注意事项
1、虽然启动线程要比启动进程要快,但是启动线程仍是比较耗时的,因此,不要频繁的启动、退出线程,而是启动线程后将各种任务处理完成后才退出(这种和线程池差不多);
2、对窗口各种组件操作,最好是在创建该窗口的线程上进行操作,如果在其它线程上操作,可能会引起程序出错等情况(该错误是随机出现的)。(未找到直接又安全的调用其他线程创建的组件的方法,有知道的人,麻烦告诉一下,谢谢!)
3、线程运行次序并不是按照我们创建他们时的顺序来运行的,CPU处理线程的顺序也是不确定的。
4、读/写共享资源时一般需要使用许可区,当然,在明知读/写共享资源不会出现错误时,就不需要许可区,这样可提高性能。
5、在编写多线程时,必须以多线程的方式考虑读/写共享资源,以避免出错,不然的话,可能会出现各种问题,如:意外退出、在单核CPU上可以稳定运行的多线程程序一到多核CPU上运行就出错。
6、线程中如果需要使用COM对象时,要需将COM对象初始化。
7、结束线程时,应该使用正常的控制代码使线程退出,强烈反对使用强制结束线程(),该命令极可能造成一些资源未释放,从而导致程序的不稳定。
8、线程不能频繁的发消息给窗口,频繁的发消息给窗口,可能会造成窗口响应其他事件的缓慢,也是就让人感觉程序运行很慢;
9、要注意避免各种死锁、活锁发生,确实无法避免的话,就只能想法解锁,同时得注意解锁时引发的新的问题。
三、多线程的误区
1、使用处理事件()。非窗口的线程是没有窗口消息循环,而处理事件()命令是用于消息循环,因此在非窗口的线程上是不必加入“处理事件()”命令;
2、线程越多越好。线程并非越多越好,有些人将单线程改成多线程后,发现程序能处理更多的任务了,实际上这种方法是建立别的程序的痛苦之上(当然系统有空闲资源就并当别论了),别的程序可能因此而变慢。并且,线程数过多,会使CPU在线程间切换的开销增加,因而使速度变慢,降低系统性能。在一些阻塞式、耗资源少的线程上需要适当的增加线程数量,以免程序无响应。
四、许可区
1、许可区(一般称为临界区),不论是硬件许可资源,还是软件许可资源,多个线程必须互斥地对它进行访问,每个线程中访问许可资源的那段代码称为许可区。
2、注意事项:
①、如果有若干线程要求进入许可区,一次仅允许一个线程进入;
②、任何时候,处于许可区内的线程不可多于一个。如已有线程进入自己的许可区,则其它所有试图进入许可区的线程将被挂起,并一直持续到进入许可区的线程退出;
③、进入一个空闲的许可区时,耗时极少,但是进入一个需等待的许可区时,耗时相对较长,因此需要避免经常出现进入需等待的许可区;
④、创建后许可区,在不再使用时,需要将其删除;
⑤、在使用许可区时,应尽量减少许可区内代码,避免使用需长时间处理的代码,使进入许可区的线程能尽快退出,以便其它线程能进入许可区;
⑥、避免将整个线程处于许可区内,尽管它不会出错,但是由于后来要求进入许可区的线程全部会被挂起,也就会出现虽然是多线程,但实际是以单线程方式执行;
⑦、访问相同的许可资源时,必须是以相同的许可区进入访问,以不同的许可区进入访问将可能会使许可区变的无意义(我在这个坑里蹲了很久,郁闷啊!)。
3、许可区缺点
①、无法侦测某个许可区是否可进入。
五、线程同步
1、临界区(CriticalSection)
易语言中称为许可区,这种速度最快,但只能用于本进程的线程同步;
2、事件(Event)
事件可以跨进程使用,它有两种状态、两种类型:有信号状态和无信号状态、手动重置事件和自动重置事件。手动重置事件被设置为有信号状态后,会唤醒所有等待的线程,而且一直保持为有信号状态,直到程序重新把它设置为无信号状态。自动重置事件被设置为有信号状态后,会唤醒“一个”等待中的线程,然后自动恢复为无信号状态。
3、互斥器(Mutex)
互斥器的功能和临界区很相似,互斥器所花费的时间比临界区多的多,同时它可以跨进程使用。等待一个被锁住的互斥器可以设定超时退出,不会像临界区那样无法得知临界区的情况,而一直死等。
4、信号量(Semaphore)
与临界区相比,它信号量可以跨进程使用,可以设定同时进入资源总数。
六、线程通信
线程通信是一般都是需要配合线程同步来使用:
1、使用全局变量进行通信,推荐使用这种方法,该是最快、最方便的通信方式;
2、使用消息通信(需要有消息队列才能使用);
3、使用Socket进行通信(可以跨计算机使用);


附:更正一下:对象.发送信息()、对象.投递信息()多线程中也不是稳定的,应该使用SendMessage()、PostMessage()。

本帖被以下淘专辑推荐:

结帖率:75% (3/4)

签到天数: 1 天

发表于 2019-10-16 07:41:02 | 显示全部楼层   浙江省温州市
太好了,受益非浅,看完恍然大悟,难怪我的老是卡死
回复 支持 反对

使用道具 举报

发表于 2018-7-3 17:01:37 高大上手机用户 | 显示全部楼层   山东省德州市
确实写的太好了
回复 支持 反对

使用道具 举报

结帖率:88% (14/16)

签到天数: 3 天

发表于 2018-4-3 09:46:53 | 显示全部楼层   福建省泉州市
这篇文章非常好,期待大神能告知,怎么在线程里面安全操作组件。
回复 支持 反对

使用道具 举报

结帖率:91% (107/118)

签到天数: 15 天

发表于 2018-3-20 00:58:06 | 显示全部楼层   广东省东莞市
算是知道这几个所谓的 概念了
回复 支持 反对

使用道具 举报

结帖率:80% (4/5)
发表于 2017-5-21 07:49:47 | 显示全部楼层   上海市上海市
不错不错!!
回复 支持 反对

使用道具 举报

结帖率:100% (1/1)
发表于 2017-2-21 22:32:20 | 显示全部楼层   广东省深圳市
感谢分享,受教
回复 支持 反对

使用道具 举报

结帖率:81% (17/21)

签到天数: 2 天

发表于 2016-9-1 11:09:07 高大上手机用户 | 显示全部楼层   河北省邢台市
留个记号,支持下
回复 支持 反对

使用道具 举报

结帖率:0% (0/2)
发表于 2015-11-7 12:38:06 | 显示全部楼层   湖南省娄底市
写的很详细,多谢分享
回复 支持 反对

使用道具 举报

结帖率:100% (4/4)
发表于 2015-11-7 07:40:10 高大上手机用户 | 显示全部楼层   山东省济南市
确实是好文章,可惜看不懂
回复 支持 反对

使用道具 举报

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

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 诚聘英才| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 800073686,邮箱:800073686@b.qq.com
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表