引子

这几天在写一个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. 所谓的规范以及JDK api文档的重要性

    所谓的规范,就是在jee api 文档里对应的接口. 可以从jdk文档和jee文档的目录结构,接口中获取对整个编程范围的把握

  2. linux上定时运行scrapy

    1 运行方式一 (proxy-ip) [root@192 ~]# cd /data/test-proxy-ip/ (proxy-ip) [root@192 test-proxy-ip]# scrapy ...

  3. CentOS 7 目录布局变化

    /bin转移到/usr/bin;/sbin转移到/usr/sbin;/lib转移到/usr/lib;/lib64转移到/usr/lib64. /var/run符号连接到/run;/var/lock符号 ...

  4. mysql 试图

    关系型数据库中的数据是由一张一张的二维关系表所组成,简单的单表查询只需要遍历一个表,而复杂的多表查询需要将多个表连接起来进行查询任务.对于复杂的查询事件,每次查询都需要编写MySQL代码效率低下.为了 ...

  5. MySQL主从数据一致性问题修复

    MySQL主从数据一致性问题修复 前面,我们使用pt-table-checksum 可以检测出主从数据是否一致的问题.发现问题后,我们怎么解决这些问题,也是我们必须要会的技能. 修复主从数据一致性问题 ...

  6. Python mode_+

    f = open("葫芦小金刚", mode="r+", encoding="utf-8") content = f.read(2) # 顺 ...

  7. 自定义页签logo

    1.webpack.prod.conf new HtmlWebpackPlugin({ filename: process.env.NODE_ENV === 'testing' ? 'index.ht ...

  8. 使用easyui将json数据生成数据表格

    1.首先需要用script引入jquery和easyui文件.如图所示: 2.html页面设置如下: data-options里面设置的属性可根据需要自己定义,是否单选,是否设置分页等等. 3.引入e ...

  9. Foundation--NSString , array and Dictionary

    一,NSString的创建 NSString*str=@" a string ";//直接创建一个字符串常量,这样创建出来的字符串不需要释放内存 NSLog(@"%@&q ...

  10. ListBox item Sort

    将Rss内容读取到Listbox control中, 然后实现按照标题或发布日期进行排序. private void ListItemSort(string type) { if (type == & ...