




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C 多线程编程实例实战多线程编程实例实战 问题的提出 所谓单个写入程序 多个阅读程序的线程同步问题 是指任意数量的线程访问共享资 源时 写入程序 线程 需要修改共享资源 而阅读程序 线程 需要读取数据 在这个 同步问题中 很容易得到下面二个要求 1 当一个线程正在写入数据时 其他线程不能写 也不能读 2 当一个线程正在读入数据时 其他线程不能写 但能够读 在数据库应用程序环境中经常遇到这样的问题 比如说 有 n 个最终用户 他们都要 同时访问同一个数据库 其中有 m 个用户要将数据存入数据库 n m 个用户要读取数据库 中的记录 很显然 在这个环境中 我们不能让两个或两个以上的用户同时更新同一条记录 如 果两个或两个以上的用户都试图同时修改同一记录 那么该记录中的信息就会被破坏 我们也不让一个用户更新数据库记录的同时 让另一用户读取记录的内容 因为读取 的记录很有可能同时包含了更新和没有更新的信息 也就是说这条记录是无效的记录 实现分析 规定任一线程要对资源进行写或读操作前必须申请锁 根据操作的不同 分为阅读锁 和写入锁 操作完成之后应释放相应的锁 将单个写入程序 多个阅读程序的要求改变一下 可以得到如下的形式 一个线程申请阅读锁的成功条件是 当前没有活动的写入线程 一个线程申请写入锁的成功条件是 当前没有任何活动 对锁而言 的线程 因此 为了标志是否有活动的线程 以及是写入还是阅读线程 引入一个变量 m nActive 如果 m nActive 0 则表示当前活动阅读线程的数目 如果 m nActive 0 则 表示没有任何活动线程 m nActive 0 表示当前有写入线程在活动 注意 m nActive 0 时只能取 1 的值 因为只允许有一个写入线程活动 为了判断当前活动线程拥有的锁的类型 我们采用了线程局部存储技术 请参阅其它 参考书籍 将线程与特殊标志位关联起来 申请阅读锁的函数原型为 public void AcquireReaderLock int millisecondsTimeout 其中的参数为线程等待调度的时间 函数定义如下 public void AcquireReaderLock int millisecondsTimeout m mutext 很快可以得到 以便进入临界区 m mutex WaitOne 是否有写入线程存在 bool bExistingWriter m nActive 0 if bExistingWriter 等待阅读线程数目加 1 当有锁释放时 根据此数目来调度线程 m nWaitingReaders else 当前活动线程加 1 m nActive m mutex ReleaseMutex 存储锁标志为 Reader System LocalDataStoreSlot slot Thread GetNamedDataSlot m strThreadSlotName object obj Thread GetData slot LockFlags flag LockFlags None if obj null flag LockFlags obj if flag LockFlags None Thread SetData slot LockFlags Reader else Thread SetData slot LockFlags int flag int LockFlags Reader if bExistingWriter 等待指定的时间 this m aeReaders WaitOne millisecondsTimeout true 它首先进入临界区 用以在多线程环境下保证活动线程数目的操作的正确性 判断当 前活动线程的数目 如果有写线程 m nActive 0 则可以让读线程继续运行 申请写入锁的函数原型为 public void AcquireWriterLock int millisecondsTimeout 其中的参数为等待调度的时间 函数定义如下 public void AcquireWriterLock int millisecondsTimeout m mutext 很快可以得到 以便进入临界区 m mutex WaitOne 是否有活动线程存在 bool bNoActive m nActive 0 if bNoActive m nWaitingWriters else m nActive m mutex ReleaseMutex 存储线程锁标志 System LocalDataStoreSlot slot Thread GetNamedDataSlot myReaderWriterLockDataSlot object obj Thread GetData slot LockFlags flag LockFlags None if obj null flag LockFlags Thread GetData slot if flag LockFlags None Thread SetData slot LockFlags Writer else Thread SetData slot LockFlags int flag int LockFlags Writer 如果有活动线程 等待指定的时间 if bNoActive this m aeWriters WaitOne millisecondsTimeout true 它首先进入临界区判断当前活动线程的数目 如果当前有活动线程存在 不管是写线 程还是读线程 m nActive 线程将等待指定的时间并且等待的写入线程数目加 1 否则 线程拥有写的权限 释放阅读锁的函数原型为 public void ReleaseReaderLock 函数定义如下 public void ReleaseReaderLock System LocalDataStoreSlot slot Thread GetNamedDataSlot m strThreadSlotName LockFlags flag LockFlags Thread GetData slot if flag LockFlags None return bool bReader true switch flag case LockFlags None break case LockFlags Writer bReader false break if bReader return Thread SetData slot LockFlags None m mutex WaitOne AutoResetEvent autoresetevent null this m nActive if this m nActive 0 if this m nWaitingReaders 0 m nActive m nWaitingReaders autoresetevent this m aeReaders else if this m nWaitingWriters 0 m nWaitingWriters m nActive autoresetevent this m aeWriters m mutex ReleaseMutex if autoresetevent null autoresetevent Set 释放阅读锁时 首先判断当前线程是否拥有阅读锁 通过线程局部存储的标志 然 后判断是否有等待的阅读线程 如果有 先将当前活动线程加 1 等待阅读线程数目减 1 然后置事件为有信号 如果没有等待的阅读线程 判断是否有等待的写入线程 如果有则 活动线程数目减 1 等待的写入线程数目减 1 释放写入锁与释放阅读锁的过程基本一致 可以参看源代码 注意在程序中 释放锁时 只会唤醒一个阅读程序 这是因为使用 AutoResetEvent 的原历 读者可自行将其改成 ManualResetEvent 同时唤醒多个阅读程序 此时应令 m nActive 等于整个等待的阅读线程数目 测试 测试程序取自 Net FrameSDK 中的一个例子 只是稍做修改 测试程序如下 using System using System Threading using MyThreading class Resource myReaderWriterLock rwl new myReaderWriterLock public void Read Int32 threadNum rwl AcquireReaderLock Timeout Infinite try Console WriteLine Start Resource reading Thread 0 threadNum Thread Sleep 250 Console WriteLine Stop Resource reading Thread 0 threadNum finally rwl ReleaseReaderLock public void Write Int32 threadNum rwl AcquireWriterLock Timeout Infinite try Console WriteLine Start Resource writing Thread 0 threadNum Thread Sleep 750 Console WriteLine Stop Resource writing Thread 0 threadNum finally rwl ReleaseWriterLock class App static Int32 numAsyncOps 20 static AutoResetEvent asyncOpsAreDone new AutoResetEvent false static Resource res new Resource public static void Main for Int32 threadNum 0 threadNum 20 threadNum ThreadPool QueueUserWorkItem new WaitCallback UpdateResource threadNum asyncOpsAreDone WaitOne Console WriteLine All operations have completed Console ReadLine The callback method s signature MUST match that of a System Threading TimerCallback delegate it takes an Object parameter and r
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 水利工程项目验收报告撰写
- 年绩效自评与工作总结
- 农村农业绿色发展模式探索
- 地产项目资金运作方案
- 2025中国工商银行黑龙江省分行社会招聘考试含答案
- 心理学在职场发展中的应用报告
- 2025浙江宁波江北区劳动和社会保障事务代理服务有限公司招聘编外工作人员1人备考试题及答案解析
- 养生美容化妆技巧
- 2025兴业银行成都分行社会招聘考试含答案
- 服装生产流程管理优化规定
- 阅兵中的数学知识
- 眼外伤护理业务查房
- 个人IP打造与推广实战指南
- 人身保险整本书课件电子教案全套课件教学教程
- 2024-2025年中国中小银行行业深度分析及投资规划研究建议报告
- 2025机动车维修企业安全管理员安全考试题库及参考答案
- 2024至2030年网络安全预警系统项目投资价值分析报告
- 国土空间生态保护修复工程生态成效监测评估技术导则 DB32 T 4867-2024
- 《LOGO标志设计》课件
- 2024年司法考试完整真题及答案
- 土方出土合同模板
评论
0/150
提交评论