引子

这几天在写一个windows phone平台上的service,由于Windows phone 的内核是基于Windows NT的,这也意味着写Windows Phone的Service代码与Win32更接近了。

虽然功能很少,但是一旦release出去,就像泼出去的水,如果我的代码出了Bug,用户只有更新固件才能获取更新,压力还是挺大。

主要的担心点是线程同步:

代码注册了一个系统的事件,当系统触发事件时,会调用事件相应的callback函数,而此callback与main线程不在同一个线程,自然引发了线程同步的问题。

索性再次翻开《Windows via C++》,复习一下线程同步的基础知识,写完代码与老外讨论了一下,还存在一些细节问题,顺手记录一下,以便巩固和回顾。

线程同步的本质在于保证某一个变量在被多个线程访问时仍然保持一致性。

用户模式下的线程同步:

用户模式下有以下几种同步的方式:

  • Interlocked系列函数。因为代码执行的原子操作是一条CPU指令而不是一句代码,一句 a++ 都是由几条指令组成的。InterlockedXXX的一系列函数能够保证对资源的操作是原子性的。
  • CRITICAL_SECTION结构体,可以用InitializeCriticalSection()和DeleteCriticalSection()函数来初始化和删除结构体,而把需要同步的代码放在EnterCriticalSection()与LeaveCriticalSection()之间。
  • SRWLock,用于区分读取资源和写入资源的线程,因为多个读取线程同时访问一个资源是线程安全的。

另外要注意的是:

  • volatile关键字保证CPU从内存中读取数据而不是从寄存器中读取数据。
  • CRITICAL_SECTION能保证操作时不会有其他线程进入,当然自己也不会重入。
  • 不要长时间占用锁,在EnterCriticalSection中时间尽量保持到最少。

使用内核对象进行线程同步:

内核对象包括:进程,线程,文件,事件,timer,信号量,互斥量等。并且有触发/未触发 两种状态。内核对象可以用Handle类型表示。

  • WaitForSingleObject(handle, Time) 可以让线程等待到第一个参数指定的内核对象被触发过,或者到达第二个参数指定的超时时间,可以将时间设置为INFINITE让线程无限等待直到内核对象状态变化,而且,不占用CPU时间,此时的线程状态是Wait,而不是Ready。
  • WaitForMultiObjects(),可以等待多个内核对象的状态变化。
  • 通常可以让WaitForSingle/MulitObject来等待事件对象,可以用CreateEvent()来创建一个事件的内核对象,可以通过SetEvent()改变事件的状态,使用ResetEvent()重置事件状态。
  • 可等待的timer内核对象,可以用CreateWaitableTimer创建,使用SetWaitableTimer来触发。
  • 信号量,可以对资源进行计数。使用CreateSemaphore创建并设置最大计数,使用ReleaseSemaphore来减少资源计数。
  • 互斥量,确保一个线程独占一个资源。使用CreateMutex创建,使用ReleaseSemaphore来释放。它比CRITICAL_SECTION性能差但可以跨进程。

要注意的是:所有内核对象使用完成后都应该用CloseHandle关闭

这基本是跟Win32平台的写法一致了,只是手机的资源更紧张,要时刻考虑到电量的消耗。

Windows平台下的线程同步的更多相关文章

  1. windows核心编程---第七章 用户模式下的线程同步

    用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在 ...

  2. 【windows核心编程】 第八章 用户模式下的线程同步

    Windows核心编程 第八章 用户模式下的线程同步 1. 线程之间通信发生在以下两种情况: ①    需要让多个线程同时访问一个共享资源,同时不能破坏资源的完整性 ②    一个线程需要通知其他线程 ...

  3. 《windows核心编程系列》七谈谈用户模式下的线程同步

    用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在 ...

  4. 内核模式下的线程同步的分析(Windows核心编程)

    内核模式下的线程同步 内核模式下的线程同步是用户模式下的线程同步的扩展,因为用户模式下的线程同步有一定的局限性.但用户模式下线程同步的好处是速度快,不需要切换到内核模式(需要额外的 CPU 时间).通 ...

  5. Windows核心编程:第8章 用户模式下的线程同步

    Github https://github.com/gongluck/Windows-Core-Program.git //第8章 用户模式下的线程同步.cpp: 定义应用程序的入口点. // #in ...

  6. Windows平台下利用APM来做负载均衡方案 - 负载均衡(下)

    概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...

  7. Windows平台下的读写锁

    Windows平台下的读写锁简单介绍Windows平台下的读写锁以及实现.背景介绍Windows在Vista 和 Server2008以后才开始提供读写锁API,即SRW系列函数(Initialize ...

  8. Windows平台下使用pthreads开发多线程应用

    pthreads简介 POSIX 1003.1-2001标准定义了编写多线程应用程序的API(应用程序编程接口),这个接口通常被称为pthreads.在常见的操作系统中,例如Unix.Linux.Ma ...

  9. 【转载】Windows平台下利用APM来做负载均衡方案 - 负载均衡(下)

    概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...

随机推荐

  1. SSH key的烦恼

    ssh key即公钥.私钥对,使用这种方式比较安全也比较方便,可以不用输入用户名.密码. 配置步骤: 1.生成ssh key: ssh-keygen -t rsa -C "bjhuxiaol ...

  2. Swift语法笔记

    Guard guard是一种条件判断语句,可以类比if.assert.如果条件不符合,guard的else语句就运行,从而退出这个函数. 具体写法如下: func fooGuard(x: Int?) ...

  3. HDTunePro汉化版温度显示不正常后需要更改

    查找:2564B046000000002564B043替换:2564A848000000002564A1E6 查找:B0432F2564B046替换:A1E62F2564A848

  4. iOS plist文件的读写

    原帖:http://blog.csdn.net/totogo2010/article/details/7634185 在做iOS开发时,经常用到到plist文件,  那plist文件是什么呢? 它全名 ...

  5. Android输入法框架系统(下)

    程序焦点获取事件导致输入法显示 从上面可以知道程序获得焦点时,程序端会先间接的调用IMMS的startInput将焦点View绑定到输入法,然后会调用IMMS的windowGainFocus函数,这个 ...

  6. 导出导入grafana完整的dashboard(非单个图表)

    导出很简单,如下图操作即可 导入

  7. NBUT 1223 Friends number 2010辽宁省赛

    Time limit  1000 ms Memory limit   131072 kB Paula and Tai are couple. There are many stories betwee ...

  8. magento的xml文件解读

    其中显示页面的getChildHtml(’')函数是取xml文件中的block中的name属性的:

  9. Android Studio中设置提示函数用法

    Eclipse有一个很好的功能,就是当你代码调用某个android API时,鼠标移到对应的函数或者方法上,就会自动有一个悬浮窗提示该函数的说明(所包含的参数含义,该方法功能).迁移到Android ...

  10. Linux:rm:du命令

    RM 删除选项rm -r 递归删除,删除目录下所有 删除当前文件下所有文件呢? rm -rf * rm -f 忽略删除提醒 万千从中找到文件删除 ls |grep abc |xargs rm -f 保 ...