




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
一、关于多线程冲突问题。3.6版开始增加了多线程支持库,提供对多线程的支持,并通过实现进入许可证机制以避免多线程冲突。 多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。 线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的,但是由于CPU的速度非常快,用户感觉不到其中的区别,因此我们也不用关心它,只需要设想各个线程是同时执行即可。多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的,由此带来的线程调度,同步等问题,将在下面探讨。由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题。多线程也有它不利的一面。任何时候某个应用程序使用的线程多于一个时,如果多个线程在同一时刻试图使用相同的数据或资源,可能出现麻烦。这种情况一旦出现,程序将变得非常复杂并且难以调试。更糟的是多线程代码经常在最初开发时运行良好,在形成产品时却往往失败,原因在于有未被发现的多个线程与相同的数据或资源相互作用的情况。这使得多线程编程非常危险。因此,在编程时需要考虑在多个线程访问同一资源时产生冲突的问题:当一个线程正在访问一个进程对象时,另一个线程要改变该对象,这时可能会产生错误的结果。所以,程序员编程时要解决这种冲突。 最简单的避免线程冲突的的方法是使线程之间永远不与相同的数据或资源交互。但这不一定可行,对任何多线程程序来说,避免或最小化共享数据或资源应作为一个目标。二、下面介绍一下在Win32 基础上用API函数进行多线程编程的过程。 1、用Win32函数创建和中止线程 Win32函数库中提供了多线程控制的操作函数,包括创建线程、中止线程、建立互斥区等。首先,在应用程序的主线程或者其它活动线程的适当地方创建新的线程。创建线程的函数如下: HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ); 其中,参数lpThreadAttributes 指定了线程的安全属性,在Windows 95中被忽略;dwStackSize 指定了线程的堆栈深度;lpStartAddress 指定了线程的起始地址,一般情况为下面的原型函数:DWORD WINAPI ThreadFunc( LPVOID );lpParameter指定了线程执行时传送给线程的32位参数,即上面函数的参数;dwCreationFlags指定了线程创建的特性; lpThreadId 指向一个DWORD变量,可返回线程ID值。 如果创建成功则返回线程的句柄,否则返回NULL。 创建了新的线程后,则该线程就开始启动执行了。如果在dwCreationFlags中用了CREATE_SUSPENDED特性,那么线程并不马上执行,而是先挂起,等到调用ResumeThread后才开始启动线程,在这个过程中可以调用函数: BOOL SetThreadPriority( HANDLE hThread, int nPriority); 来设置线程的优先权。 当线程的函数返回后,线程自动中止。如果在线程的执行过程中中止的话,则可调用函数: VOID ExitThread( DWORD dwExitCode); 如果在线程的外面中止线程的话,则可调用下面的函数: 2楼BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode ); 但应注意:该函数可能会引起系统不稳定,而且线程所占用的资源也不释放。因此,一般情况下,建议不要使用该函数。 如果要中止的线程是进程内的最后一个线程,则在线程被中止后相应的进程也应中止。 2、用Win32函数控制线程对共享资源的访问 在线程体内,如果该线程完全独立,与其它的线程没有数据存取等资源操作上的冲突,则可按照通常单线程的方法进行编程。但是,在多线程处理时情况常常不是这样,线程之间经常要同时访问一些资源。例如,一个线程负责公式计算,另一个线程负责结果的显示,两个线程都要访问同一个结果变量。这时如果不进行冲突控制的话,则很可能显示的是不正确的结果。 对共享资源进行访问引起冲突是不可避免的,但我们可用以下办法来进行操作控制: (1) 通过设置线程的互斥体对象,在可能冲突的地方进行同步控制。 首先,建立互斥体对象,得到句柄: HANDLE CreateMutex( ); 然后,在线程可能冲突区域的开始(即访问共享资源之前),调用WaitForSingleObject将句柄传给函数,请求占用互斥体对象: dwWaitResult = WaitForSingleObject(hMutex, 5000L); 共享资源访问完后,释放对互斥体对象的占用: ReleaseMutex(hMutex); 互斥体对象在同一时刻只能被一个线程占用。当互斥体对象被一个线程占用时,若有另一线程想占用它,则必须等到前一线程释放后才能成功。 (2) 设置信号:在操作共享资源前,打开信号;完成操作后,关闭信号。这类似于互斥体对象的处理。 首先,创建信号对象: HANDLE CreateSemaphore( ); 或者打开一个信号对象: HANDLE OpenSemaphore( ); 然后,在线程的访问共享资源之前调用WaitForSingleObject。 共享资源访问完后,释放对信号对象的占用: ReleaseSemaphore(); 信号对象允许同时对多个线程共享资源的访问,在创建对象时指定最大可同时访问的线程数。当一个线程申请访问成功后,信号对象中的计数器减一;调用ReleaseSemaphore函数后,信号对象中的计数器加一。其中,计数器值大于等于0,小于等于创建时指定的最大值。利用信号对象,我们不仅可以控制共享资源的访问,还可以在应用的初始化时候使用。假定一个应用在创建一个信号对象时,将其计数器的初始值设为0,这样就阻塞了其它线程,保护了资源。待初始化完成后,调用ReleaseSemaphore函数将其计数器增加至最大值,进行正常的存取访问三、下面介绍易语言的多线程编程方法。通过研究易语言附带的两个多线程例程,总结如下:(一)、先看易语言对自己的多程机制的解释:1、创建进入许可证:创建并返回一个进入许可证数值,此许可证值用作进入程序中的指定许可代码区,以避免多线程冲突。2、删除进入许可证:删除由“创建进入许可证”命令所创建返回的进入许可证,以释放系统资源。3、启动线程:创建并启动一条线程,可重复使用以创建多条线程。4、进入许可区:根据已经创建的许可证进入指定许可代码区,在此线程未退出之前,其它线程如要通过同一个进入许可证进入该许可代码区则必须先等待此线程退出许可代码区,从而保证了指定许可代码区在任何时候都只能有一条线程进入并执行。5、退出许可区:指示当前线程将退出许可代码区,并允许其它使用同一进入许可证的线程进入此许可代码区。(二)、易语言的多线程编程过程大约如下: 3楼1、先用“创建进入许可证”命令为一个线程进入一个指定的许可代码区建立一个许可证。 2、用“启动线程”命令创建并启动一条线程,以运行一个线程的子程序。 3、在一个线程子程序里用“进入许可区”使该线程占用一个许可代码区,并锁定该代码区不让其他线程进入,并锁定其他线程运行,以避免线程冲突。 4、使用“退出许可区”解锁该许可代码区,以便让其他线程进入。若想使多个线程同时运行,我们可以为每个线程建立一个进入许可证,进入许可区与退出许可区连着进行使多个线程同步运行。5、当退出程序时,要删除进入许可证以释放系统资源。(三)、下面的示例代码同时运行两个线程,一个是连续随机画圆,一个是连续随机画矩形:窗口程序集:窗口程序集1 程序集变量:进入许可证1 数据类型:整数型程序集变量:画圆判断 数据类型:逻辑型程序集变量:画矩形判断 数据类型:逻辑型程序集变量:进入许可证2 数据类型:整数型 子程序:_按钮1_被单击 备注:如果按钮1的标题为“停止画圆”时就开始画圆(画圆判断 假),否则如果按钮1的标题为“开始画圆”时就停止画圆(画圆判断 真)。画圆判断 取反 (画圆判断)判断 (画圆判断 真)如果 (进入许可证1 0)如果真 (启动线程 (&画圆线程) 真)按钮1.标题 “停止画圆”如果真结束否则信息框 (“创建进入许可证 失败”, 0, )如果结束默认按钮1.标题 “开始画圆”判断结束 子程序:画圆线程判断循环首 (画圆判断 真)置随机数种子 ()画板1.刷子颜色 取颜色值 (取随机数 (0, 255), 取随机数 (0, 255), 取随机数 (0, 255)画板1.画笔颜色 取颜色值 (取随机数 (0, 255), 取随机数 (0, 255), 取随机数 (0, 255)画板1.画椭圆 (取随机数 (1, 画板1.宽度), 取随机数 (1, 画板1.高度), 取随机数 (1, 画板1.宽度), 取随机数 (1, 画板1.高度)进入许可区 (进入许可证1)退出许可区 (进入许可证1)延时 (500)判断循环尾 () 子程序:_启动窗口_创建完毕进入许可证1 创建进入许可证 ()进入许可证2 创建进入许可证 () 子程序:_启动窗口_将被销毁删除进入许可证 (进入许可证1)删除进入许可证 (进入许可证2) 子程序:_按钮2_被单击画矩形判断 取反 (画矩形判断)判断 (画矩形判断 真)如果 (进入许可证2 0)如果真 (启动线程 (&画矩形线程) 真)按钮2.标题 “停止画矩形”如果真结束否则信息框 (“创建进入许可证 失败”, 0, )如果结束默认按钮2.标题 “开始画矩形”判断结束 子程序:画矩形线程判断循环首 (画矩形判断 真)置随机数种子 ()画板2.刷子颜色 取颜色
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中等教育中情绪管理教育的跨学科合作模式探索考核试卷
- 低温仓储节能减排技术标准国际化趋势分析考核试卷
- 氧化还原反应及其应用(测)-2023年高考化学二轮复习(新高考专用)
- 安理工选矿学课件第5章 跳汰选矿
- 电梯设备定期检验维护制
- 北京市平谷区2024-2025学年七年级下学期期末道德与法治试题(含答案)
- 2024-2025学年甘肃省临夏州高二(下)期末数学试卷(含答案)
- AI+时代下如何构建可持续发展的区域科技创新服务体系
- 文言文阅读之形象分析(讲义)解析版-2026年中考语文一轮复习之古诗文
- 铁路客运员(中级)职业技能考试题(附答案)
- 正念在儿童教育中的实践与效能
- 个人信息保护及隐私管理制度
- 鲁教版(五四学制)中考英语6-9年级词汇表
- GB/T 43635-2024法庭科学DNA实验室检验规范
- 福建医科大学临床医学继续教育第一学期英语期末试卷
- 投资管理ETF与指数基金的投资策略
- 土石方弃土消纳与处理协议
- 市场竞争策略调整建议
- 万魔声学股份有限公司供应商现场审核评分表QSA+QPA-Checklist+自评回复样板
- 已完工程量转让协议
- 高中班主任如何开展德育工作
评论
0/150
提交评论