多线程的那点儿事(之windows锁)

在windows系统中,系统本身为我们提供了很多锁。通过这些锁的使用,一方面可以加强我们对锁的认识,另外一方面可以提高代码的性能和健壮性。常用的锁以下四种:临界区,互斥量,信号量,event。

(1)临界区

临界区是最简单的一种锁。基本的临界区操作有,

[cpp] view plaincopy

  1. InitializeCriticalSection
  2. EnterCriticalSection
  3. LeaveCriticalSection
  4. DeleteCriticalSection

如果想要对数据进行互斥操作的话,也很简单,这样做就可以了,

[cpp] view plaincopy

  1. EnterCriticalSection(/*...*/)
  2. do_something();
  3. LeaveCriticalSection(/*...*/)

(2)互斥锁
    互斥锁也是一种锁。和临界区不同的是,它可以被不同进程使用,因为它有名字。同时,获取锁和释放锁的线程必须是同一个线程。常用的互斥锁操作有

[cpp] view plaincopy

  1. CreateMutex
  2. OpenMutex
  3. ReleaseMutex

那么,怎么用互斥锁进行数据的访问呢,其实不难。

[cpp] view plaincopy

  1. WaitForSingleObject(/*...*/);
  2. do_something();
  3. ReleaseMutex(/*...*/);

(3)信号量
  
 信号量是使用的最多的一种锁结果,也是最方便的一种锁。围绕着信号量,人们提出了很多数据互斥访问的方案,pv操作就是其中的一种。如果说互斥锁只能对
单个资源进行保护,那么信号量可以对多个资源进行保护。同时信号量在解锁的时候,可以被另外一个thread进行解锁操作。目前,常用的信号量操作有,

[cpp] view plaincopy

  1. CreateSemaphore
  2. OpenSemaphore
  3. ReleaseSemaphore

信号量的使用和互斥锁差不多。关键是信号量在初始化的时候需要明确当前资源的数量和信号量的初始状态是什么,

[cpp] view plaincopy

  1. WaitForSingleObject(/*...*/);
  2. do_something();
  3. ReleaseSemaphore(/*...*/);

(4)event对象
  
 event对象是windows下面很有趣的一种锁结果。从某种意义上说,它和互斥锁很相近,但是又不一样。因为在thread获得锁的使用权之前,常
常需要main线程调用SetEvent设置一把才可以。关键是,在thread结束之前,我们也不清楚当前thread获得event之后执行到哪了。
所以使用起来,要特别小心。常用的event操作有,

[cpp] view plaincopy

  1. CreateEvent
  2. OpenEvent
  3. PulseEvent
  4. ResetEvent
  5. SetEvent

我们对event的使用习惯于分成main thread和normal thread使用。main
thread负责event的设置和操作,而normal
thread负责event的等待操作。在CreateEvent的时候,要务必考虑清楚event的初始状态和基本属性。
    对于main thread,应该这么做,

[cpp] view plaincopy

  1. CreateEvent(/*...*/);
  2. SetEvent(/*...*/);
  3. WaitForMultiObjects(hThread, /*...*/);
  4. CloseHandle(/*...*/);

对于normal thread来说,操作比较简单,

[cpp] view plaincopy

  1. while(1){
  2. WaitForSingleObject(/*...*/);
  3. /*...*/
  4. }

总结:
    (1)关于临界区互斥区信号量event在msdn上均有示例代码
    (2)一般来说,使用频率上信号量 > 互斥区 > 临界区 > 事件对象
    (3)信号量可以实现其他三种锁的功能,学习上应有所侧重
    (4)纸上得来终觉浅,多实践才能掌握它们之间的区别

多线程的那点儿事(之windows锁)

时间: 2024-08-13 21:22:36

多线程的那点儿事(之windows锁)的相关文章

多线程的那点儿事(之自旋锁)

自旋锁是SMP中经常使用到的一个锁.所谓的smp,就是对称多处理器的意思.在工业用的pcb板上面,特别是服务器上面,一个pcb板有多个cpu是 很正常的事情.这些cpu相互之间是独立运行的,每一个cpu均有自己的调度队列.然而,这些cpu在内存空间上是共享的.举个例子说,假设有一个数据 value = 10,那么这个数据可以被所有的cpu访问.这就是共享内存的本质意义. 我们可以看一段Linux 下的的自旋锁代码(kernel 2.6.23,asm-i386/spinlock.h),就可有清晰的

多线程的那点儿事(之生产者-消费者)

生产者-消费者是很有意思的一种算法.它的存在主要是两个目的,第一就是满足生产者对资源的不断创造:第二就是满足消费者对资源的不断索取.当然,因为空间是有限的,所以资源既不能无限存储,也不能无限索取. 生产者的算法, [cpp] view plaincopy WaitForSingleObject(hEmpty, INFINITE); WaitForSingleObject(hMutex, INIFINITE); /* produce new resources */ ReleaseMutex(hM

多线程(JDK1.5的新特性互斥锁)(掌握)

多线程(JDK1.5的新特性互斥锁)(掌握)1.同步·使用ReentrantLock类的lock()和unlock()方法进行同步2.通信·使用ReentrantLock类的newCondition()方法可以获取Condition对象·需要等待的时候使用Condition的await()方法, 唤醒的时候用signal()方法·不同的线程使用不同的Condition, 这样就能区分唤醒的时候找哪个线程了举例: public static void main(String[] args) { f

多线程的那点儿事(基础篇)

多线程编程是现代软件技术中很重要的一个环节.要弄懂多线程,这就要牵涉到多进程?当然,要了解到多进程,就要涉及到操作系统.不过大家也不要紧张,听我慢慢道来.这其中的环节其实并不复杂. (1)单CPU下的多线程 在没有出现多核CPU之前,我们的计算资源是唯一的.如果系统中有多个任务要处理的话,那么就需要按照某种规则依次调度这些任务进行处理.什么规则呢?可以是一些简单的调度方法,比如说 1)按照优先级调度 2)按照FIFO调度 3)按照时间片调度等等 当然,除了CPU资源之外,系统中还有一些其他的资源

“全栈2019”Java多线程第三十章:尝试获取锁tryLock()方法详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第三十章:尝试获取锁tryLock()方法详解 下一章 "全栈2019"Java多线程第三十一章:中断正在等待显式锁的线程 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复

“全栈2019”Java多线程第四十七章:判断锁是否为公平锁isFair()

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第四十七章:判断锁是否为公平锁isFair() 下一章 "全栈2019"Java多线程第四十八章:读写锁实战高并发容器 学习小组 加入同步学习小组,共同交流与进步. 方式一:加入编程圈子. 方式二:关注头条号Gorhaf,私信"Java学习小组". 方式三:关注公众

关于Windows锁屏对WPF渲染的影响

在一个风和日丽的工作日,我日常打开VS,打开公司项目,打开调试,继续解决我之前存在的一个bug, 这个bug不一般,在经过连续几个星期的测试后,总结出了以下特点: 1.bug表现在交互上,最先表示为卡死状态,且复现过程为把电脑放置一段时间后,再操作界面出现的问题: 2.深入测试我们进一步发现,此bug不同于一般的卡死bug,此bug在电脑放置一段时间卡死后,能拖动窗口,甚至我在ViewModel中写的控制台输出都能正常输出日志: 3.再深入一点我们发现,此bug还能在发生后恢复,此bug出现后是

多线程的那点儿事(之原子锁)

[ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com]    原子锁是多线程编程中的一个特色.然而,在平时的软件编写中,原子锁的使用并不是很多.这其中原因很多,我想主要有两个方面.第一,关于原子锁这方面的内容介绍的比较少:第二,人们在编程上面习惯于已有的方案,如果没有特别的需求,不过贸然修改已存在的代码.毕竟对很多人来说,不求有功,但求无过.保持当前代码的稳定性还是很重要的.      其实,早在<多线程数据互斥>这篇博客中,我们就已经介绍过原

多线程的那点儿事(之数据同步)

[ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 多线程创建其实十分简单,在windows系统下面有很多函数可以创建多线程,比如说_beginthread.我们就可以利用它为我们编写一段简单的多线程代码, [cpp] view plaincopy #include <windows.h> #include <process.h> #include <stdio.h> unsigned int value = 0;