![C多线程编程实例实战剖析_第1页](http://file2.renrendoc.com/fileroot_temp3/2021-6/9/fa06c79d-63fc-4142-bde8-ac843e6dae50/fa06c79d-63fc-4142-bde8-ac843e6dae501.gif)
![C多线程编程实例实战剖析_第2页](http://file2.renrendoc.com/fileroot_temp3/2021-6/9/fa06c79d-63fc-4142-bde8-ac843e6dae50/fa06c79d-63fc-4142-bde8-ac843e6dae502.gif)
![C多线程编程实例实战剖析_第3页](http://file2.renrendoc.com/fileroot_temp3/2021-6/9/fa06c79d-63fc-4142-bde8-ac843e6dae50/fa06c79d-63fc-4142-bde8-ac843e6dae503.gif)
![C多线程编程实例实战剖析_第4页](http://file2.renrendoc.com/fileroot_temp3/2021-6/9/fa06c79d-63fc-4142-bde8-ac843e6dae50/fa06c79d-63fc-4142-bde8-ac843e6dae504.gif)
![C多线程编程实例实战剖析_第5页](http://file2.renrendoc.com/fileroot_temp3/2021-6/9/fa06c79d-63fc-4142-bde8-ac843e6dae50/fa06c79d-63fc-4142-bde8-ac843e6dae505.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C#多线程编程实例实战问题的提出所谓单个写入程序 /多个阅读程序的线程同步问题, 是指任意数量的线程访问共享资源 时,写入程序(线程)需要修改共享资源,而阅读程序(线程)需要读取数据。在这个同步 问题中,很容易得到下面二个要求:1)当一个线程正在写入数据时,其他线程不能写,也不能读。2)当一个线程正在读入数据时,其他线程不能写,但能够读。在数据库应用程序环境中经常遇到这样的问题。比如说,有 n 个最终用户,他们都要 同时访问同一个数据库。其中有 m 个用户要将数据存入数据库, n-m 个用户要读取数据库 中的记录。很显然,在这个环境中,我们不能让两个或两个以上的用户同时更新同一条记录,如 果两
2、个或两个以上的用户都试图同时修改同一记录,那么该记录中的信息就会被破坏。我们也不让一个用户更新数据库记录的同时,让另一用户读取记录的内容。因为读取 的记录很有可能同时包含了更新和没有更新的信息,也就是说这条记录是无效的记录。实现分析规定任一线程要对资源进行写或读操作前必须申请锁。根据操作的不同,分为阅读锁 和写入锁, 操作完成之后应释放相应的锁。将单个写入程序 /多个阅读程序的要求改变一下, 可以得到如下的形式:一个线程申请阅读锁的成功条件是:当前没有活动的写入线程。一个线程申请写入锁的成功条件是:当前没有任何活动(对锁而言)的线程。因此,为了标志是否有活动的线程,以及是写入还是阅读线程,引入
3、一个变量 m_nActive ,如果 m_nActive 0 ,则表示当前活动阅读线程的数目,如果 m_nActive=0 ,则 表示没有任何活动线程, m_nActive 0 ,表示当前有写入线程在活动,注意 m_nActive0 , 时只能取 -1 的值,因为只允许有一个写入线程活动。为了判断当前活动线程拥有的锁的类型,我们采用了线程局部存储技术(请参阅其它 参考书籍),将线程与特殊标志位关联起来。申请阅读锁的函数原型为: public void AcquireReaderLock( int millisecondsTimeout ) , 其中的参数为线程等待调度的时间。函数定义如下:pu
4、blic void AcquireReaderLock( int millisecondsTimeout )/ m_mutext 很快可以得到,以便进入临界区 m_mutex.WaitOne( );/ 是否有写入线程存在bool bExistingWriter = ( m_nActive 0 );if( bExistingWriter ) / 等待阅读线程数目加 1,当有锁释放时,根据此数目来调度线程 m_nWaitingReaders+;else / 当前活动线程加 1m_nActive+;m_mutex.ReleaseMutex();/存储锁标志为 ReaderSystem.LocalDa
5、taStoreSlot 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 );elseThread.SetData( slot, (LockFlags)(int)flag | (int)LockF
6、lags.Reader ) );if( bExistingWriter ) / 等待指定的时间this.m_aeReaders.WaitOne( millisecondsTimeout, true );它首先进入临界区(用以在多线程环境下保证活动线程数目的操作的正确性)判断当 前活动线程的数目,如果有写线程 (m_nActive=0) ,则可以让读线程继续运行。申请写入锁的函数原型为: public void AcquireWriterLock( int millisecondsTimeout ) ,其 中的参数为等待调度的时间。函数定义如下:public void AcquireWriter
7、Lock( int millisecondsTimeout )/ m_mutext 很快可以得到,以便进入临界区m_mutex.WaitOne( );/ 是否有活动线程存在bool bNoActive = m_nActive = 0;if( !bNoActive )m_nWaitingWriters+;elsem_nActive-;m_mutex.ReleaseMutex();/存储线程锁标志System.LocalDataStoreSlot slot = Thread.GetNamedDataSlot( myReaderWriterLockDataSlot ); object obj = T
8、hread.GetData( slot );LockFlags flag = LockFlags.None;if( obj != null )flag = (LockFlags)Thread.GetData( slot );if( flag = LockFlags.None )Thread.SetData( slot, LockFlags.Writer );elseThread.SetData( slot, (LockFlags)(int)flag | (int)LockFlags.Writer ) );/如果有活动线程,等待指定的时间if( !bNoActive )this.m_aeWrit
9、ers.WaitOne( millisecondsTimeout, true );它首先进入临界区判断当前活动线程的数目,如果当前有活动线程存在,不管是写线 程还是读线程( m_nActive ),线程将等待指定的时间并且等待的写入线程数目加1,否则线程拥有写的权限。释放阅读锁的函数原型为:public void ReleaseReaderLock() 。函数定义如下:public void ReleaseReaderLock()System.LocalDataStoreSlot slot = Thread.GetNamedDataSlot(m_strThreadSlotName );Lock
10、Flags 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
11、;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 ) autorese
12、tevent.Set();释放阅读锁时, 首先判断当前线程是否拥有阅读锁 (通过线程局部存储的标志) ,然后 判断是否有等待的阅读线程,如果有,先将当前活动线程加 1,等待阅读线程数目减 1,然 后置事件为有信号。 如果没有等待的阅读线程, 判断是否有等待的写入线程, 如果有则活动 线程数目减 1,等待的写入线程数目减 1。释放写入锁与释放阅读锁的过程基本一致,可以 参看源代码。注意在程序中,释放锁时,只会唤醒一个阅读程序,这是因为使用 AutoResetEvent 的 原历,读者可自行将其改成 ManualResetEvent ,同时唤醒多个阅读程序, 此时应令 m_nActive 等于整个
13、等待的阅读线程数目。测试测试程序取自 .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
14、=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.W
15、riteLine(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; thre
16、adNum+) ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateResource), threadNum);asyncOpsAreDone.WaitOne();Console.WriteLine(All operations have completed.);Console.ReadLine();/ The callback methods signature MUST match that of a System.Threading.TimerCallback/ delegate (it takes an Object parameter and return
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 胸外科护士工作心得
- 2025年全球及中国单摆铣头行业头部企业市场占有率及排名调研报告
- 2025-2030全球倒置行星滚柱丝杠行业调研及趋势分析报告
- 2025年全球及中国虚拟试穿平台行业头部企业市场占有率及排名调研报告
- 2025年全球及中国汽车天线定位器行业头部企业市场占有率及排名调研报告
- 2025年全球及中国重载有轨穿梭小车(RGV)行业头部企业市场占有率及排名调研报告
- 2025年全球及中国丝素蛋白敷料行业头部企业市场占有率及排名调研报告
- 2025-2030全球直线式桁架机器人行业调研及趋势分析报告
- 2025-2030全球装运前检验(PSI)服务行业调研及趋势分析报告
- 2025年全球及中国电子钥匙柜行业头部企业市场占有率及排名调研报告
- 江西省部分学校2024-2025学年高三上学期1月期末英语试题(含解析无听力音频有听力原文)
- GA/T 2145-2024法庭科学涉火案件物证检验实验室建设技术规范
- 2024年中考语文试题分类汇编:非连续性文本阅读(学生版)
- 2024年度窑炉施工协议详例细则版B版
- 第一届山东省职业能力大赛济南市选拔赛制造团队挑战赛项目技术工作文件(含样题)
- 尿毒症替代治疗
- 【课件】2025届高考英语一轮复习小作文讲解课件
- 基底节脑出血护理查房
- 工程公司总经理年终总结
- 2024年海南省高考地理试卷(含答案)
- 【企业盈利能力探析的国内外文献综述2400字】
评论
0/150
提交评论