您的位置:首页 > 其它

八、 用户模式下的线程同步

2013-05-30 11:28 162 查看
1. 在一下两种基本情况下,线程之间需要相互通信:

(1). 需要让多个线程同时访问一个共享资源,同时不能破环资源的完整性

(2) . 一个线程需要通知其他线程某些任务已完成。

2. 原子访问。 Interlocked 系列函数

Iterlocked在x86的实现方式: Interlocked会在总线上维持一个硬件信号,这个信号会阻止其他cpu访问同一内存地址

关键段(critical section)的实现方式: 许多开发人员会循环指定次数,如果届时无法访问资源,那么线程会切换到内核模式,并一直等待资源可供使用为止(此时不消耗cpu时间)

调用Interlocked需要大约50个周期,切换用户/内核模式需要1000周期,使用cpu周期来计算程序的运行时间。

3. 高速缓存(32字节,64字节或128)

当cpu从内存中读取一个字节时, 它并不只是从内存中取回一个字节,而是取回一个高速缓存行。高速缓存行在多处理器环境需要处理。当某个cpu更改了其缓存行内容,需要通知其他cpu将该地址的缓存作废。

4. 在设计数据时应该注意:将只读,读写分开存放等。 p204设计糟糕的数据结构及其改进。

5. 高级线程同步: 既等待共享资源的访问权,又不浪费cpu时间。

如果无法取得对资源的访问权,或者特殊时间尚未发生,那么系统会将线程切换到等待状态,将线程变得不可调度。 从而避免让线程浪费cpu时间。当线程在等待时,系统充当其助理,系统会记住线程想要访问什么资源,当资源可供使用的时候,它会自动将线程唤醒。

6. 避免使用的方法: 轮询 浪费大量cpu时间 替代方法?(tryenter?)

volatile告诉编译器,该变量可能被应用程序之外的所有其他东西修改,需要对这个变量进行任何形式的优化(存在寄存器等)。

如果变量是个地址,则可不加volatile p206

7. 关键段细节

关键段 + 旋转锁 避免频繁切换浪费大量cpu时间

8. slim 读写锁 不过进行函数包装罢了。 slim(苗条)

读写锁的缺点: 不存在tryenter, 如果锁被占用,那么调用acquireSRWlock会阻塞调用线程。不能递归获得srwlock。

(单线程情况下,读者写着程序运行不起来。需要多线程模拟各种情况。需要锁的进程,在未获得锁的时候只能轮询等待,这是没办法的事情(阻塞),要不还能做啥事)

9. 条件变量 queue

10. 以相同的顺序进入关键段或加锁,释放则无关紧要。因为该函数从来不会让线程进入等待状态。不要长时间占有锁,以标志的形式代替
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: