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

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. 以相同的顺序进入关键段或加锁,释放则无关紧要。因为该函数从来不会让线程进入等待状态。不要长时间占有锁,以标志的形式代替


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值