互斥锁

信号量与互斥锁

故事扮演 提交于 2019-12-25 03:01:19
学习Mutex的心得,不一定对,先记录一下。 同步技术分为两大类,锁定和信号同步。 锁定分为:Lock、Monitor 信号同步分为:AutoResetEvent、ManualResetEvent、Semaphore以及Mutex。他们都继承自WaitHandle, AutoResetEvent、ManualResetEvent在内存中维护一个布尔型变量,如果为false则阻塞,如果为true则解除阻塞 Semaphore在内存中维护一个整型变量,如果为0则阻塞,如果大于0则解除阻塞,每解除一个阻塞其值减一 AutoResetEvent、ManualResetEvent、Semaph提供单进程内的线程同步 Mutex提供跨应用程序域的线程阻塞和解除的能力,主要用于互斥访问。 下面是一个使用Mutex进行互斥访问的演示例子。 软件打开时,如果接收到输入则创建一个互斥锁,并持有锁,直到再次接收到输入,然后释放锁,如果再次输入又创建锁, 如此循环。 假设app1创建一个互斥锁,然后持有锁,并对共享资源进行操作,那么app2就不能再次创建互斥锁,据此就能判断共享资源释放被别的进程占用。 如果app1使用完了共享资源,释放了互斥锁,则app2就可以创建互斥锁,据此可以判断共享资源可以被访问了。 以下是app1代码 1、Mutex用于进程间的同步 using System; using

windows应用编程中的线程锁

最后都变了- 提交于 2019-12-24 11:52:01
最近在一个产测工具的一拖多的开发过程中由于涉及多线程并发,使用了EnterCriticalSection和LeaveCriticalSection来进行资源的互斥访问。由于代码编写的粗心大意,导致某个处理逻辑出错时未调用LeaveCriticalSection而存在死锁可能。 由于出错逻辑出现几率非常低,故自测时未发现,后经有其他同事参考我的代码开发其他工具时才发现。于是打算重新对代码中的互斥锁的各种代码逻辑情况进行相关测试。 由于手头上缺少样机,故打算用单台样机进行死锁问题的测试, 测试过程中偶然发现了EnterCriticalSection-LeaveCriticalSection互斥锁在单线程里面是不生效的!即当一个线程获得该锁后,尽管不释放,也是可以重入的,并不存在死锁的问题! 关于EnterCriticalSection-LeaveCriticalSection多线程互斥锁的具体使用方法可以见其他博文: https://blog.csdn.net/ninedays/article/details/5381123 来源: CSDN 作者: blacksonlgx 链接: https://blog.csdn.net/weixin_45254661/article/details/103677793

Python并发编程一(多进程)

那年仲夏 提交于 2019-12-23 21:47:58
1.背景知识(进程、多道技术) 顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一。操作系统的其他所有内容都是围绕进程的概念展开的。 了解操作系统,详见: https://www.cnblogs.com/JackLi07/p/9226851.html #一 操作系统的作用: 1:隐藏丑陋复杂的硬件接口,提供良好的抽象接口 2:管理、调度进程,并且将多个进程对硬件的竞争变得有序 #二 多道技术: 1.产生背景:针对单核,实现并发 ps: 现在的主机一般是多核,那么每个核都会利用多道技术 有4个cpu,运行于cpu1的某个程序遇到io阻塞,会等到io结束再重新调度,会被调度到4个 cpu中的任意一个,具体由操作系统调度算法决定。 2.空间上的复用:如内存中同时有多道程序 3.时间上的复用:复用一个cpu的时间片 强调:遇到io切,占用cpu时间过长也切,核心在于切之前将进程的状态保存下来,这样 才能保证下次切换回来时,能基于上次切走的位置继续运行 2.python并发编程之多进程(理论)   进程:正在进行的一个过程或者说一个任务。而负责执行任务则是cpu。 2.1进程与程序的区别   程序仅仅只是一堆代码而已,而进程指的是程序的运行过程。   需要强调的是

线程的同步

左心房为你撑大大i 提交于 2019-12-22 05:10:36
多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图。 1.互斥量 可以通过使用pthread的互斥接口保护数据,确保同一时间只有一个线程访问数据,互斥量(mutex)从本质上说是一把锁, 在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁后,任何其他试图再次对互斥 量进行加锁的线程将被阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥量进行加锁,其他线程将会看到互斥锁依然被锁住,只有回去再次等待它重新变成可用。在这种方式下,每次只有一个线程可以向前执行。 互斥变量用pthread_mutex_t数据类型来表示,在使用互斥变量以前,必须首先对它进行初始化,可以把它置为常量PTHREAD_MUTEX_INITIALIZER(只对静态分配的互斥量),也可以通过调用pthread_mutex_init函数进行初始化。如果动态地分配互斥量(例如通过调用malloc),那么在释放内存前需要调用pthread_mutex_destroy。 #include<pthread.h> int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr

乐观锁--CAS

空扰寡人 提交于 2019-12-22 00:54:42
悲观锁与乐观锁的区别 悲观锁会把整个对象加锁占为已有后才去做操作,Java中的Synchronized属于悲观锁。悲观锁有一个明显的缺点就是:它不管数据存不存在竞争都加锁,随着并发量增加,且如果锁的时间比较长,其性能开销将会变得很大。 乐观锁不获取锁直接做操作,然后通过一定检测手段决定是否更新数据,这种方式下,已经没有所谓的锁概念了,每条线程都直接先去执行操作,计算完成后检测是否与其他线程存在共享数据竞争,如果没有则让此操作成功,如果存在共享数据竞争则可能不断地重新执行操作和检测,直到成功为止。 CAS算法 乐观锁的核心算法是CAS(Compareand Swap,比较并交换),它涉及到三个操作数:内存值、预期值、新值,当且仅当预期值和内存值相等时才将内存值修改为新值。这样处理的逻辑是,首先检查某块内存的值是否跟之前我读取时的一样,如不一样则表示期间此内存值已经被别的线程更改过,舍弃本次操作,否则说明期间没有其他线程对此内存值操作,可以把新值设置给此块内存。 假如你足够细心你可能会发现一个疑问,比较和交换,从字面上就有两个操作了,更别说实际CAS可能会有更多的执行指令,他们是原子性的吗?如果非原子性又怎么保证CAS操作期间出现并发带来的问题?我是不是需要用上节提到的互斥锁来保证他的原子性操作?CAS肯定是具有原子性的,不然就谈不上在并发中使用了

进阶系列(11)—— C#多线程

自古美人都是妖i 提交于 2019-12-21 23:51:38
一、多线程的相关概念 1.进程:是操作系统结构的基础;是一个正在执行的程序;计算机中正在运行的程序实例;可以分配给处理器并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所描述的活动单元。 2.线程:线程是程序中一个单一的顺序控制流程。是程序执行流的最小单元。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。 3.多线程:在单个程序中同时运行多个线程完成不同的工作,称为多线程。 理解: 其实更容易理解一点进程与线程的话,可以举这样一个例子:把进程理解成为一个运营着的公司,然而每一个公司员工就可以叫做一个线程。每个公司至少要有一个员工,员工越多,如果你的管理合理的话,公司的运营速度就会越好。这里官味一点话就是说。cpu大部分时间处于空闲时间,浪费了cpu资源,多线程可以让一个程序“同时”处理多个事情,提高效率。 (一)单线程问题演示 创建一个WinForm应用程序,这里出现的问题是

C# 之多线程(二)

一个人想着一个人 提交于 2019-12-21 23:51:25
一、确定多线程的结束时间,thread的IsAlive属性 在多个线程运行的背景下,了解线程什么时候结束,什么时候停止是很有必要的。 案例 :老和尚念经计时,2本经书,2个和尚念,一人一本,不能撕破,最短时间念完,问老和尚们念完经书最短需要多长时间。 分析 :首先在开始念经的时候给计时,记为A,最后在记下慢和尚念完经书时的时间,记为B。求B-A 代码 :IsAlive属性:标识此线程已启动并且尚未正常终止或中止,则为 true,再念,没念完,努力中;否则为 false,念完啦,歇着。 //和尚1,和尚2 public Thread td1, td2; public void StarThread() { //开启一个线程执行Hello方法,即和尚1念菠萝菠萝蜜 ThreadStart ts = new ThreadStart(Hello); td1 = new Thread(ts); td1.Start(); } public void StarThread1() { //开启一个线程执行Welcome方法,即和尚2念大金刚经 ThreadStart ts = new ThreadStart(Welcome); td2 = new Thread(ts); td2.Start(); } public string sayh="", sayw=""; //菠萝菠萝蜜 public

python 中互斥锁 死锁

ぃ、小莉子 提交于 2019-12-21 23:46:35
互斥锁 互斥锁 : 对共享数据进行锁定, 保证同一时刻只能有一个线程去操作. 互斥锁的注意点 : 互斥锁是多个线程一起去抢, 抢到锁的线程先执行, 没有抢到锁的线程需要等待, 等互斥锁使用完释放后,其他等待的线程再去抢这个锁 互斥锁的使用 : threading 模块中定义了 Lock 变量, 这个变量本质上是一个函数, 通过调用这个函数可以获取一把互斥锁 # 创建锁 mutex = threading . Lock ( ) # 上锁 mutex . acquire ( ) 这里是同一时刻只有一个线程去操作的代码 , 对共享的数据进行锁定 # 释放锁 mutex . release ( ) 小黑板 acquire 和 release 方法之间的代码同一时刻只能有一个线程去操作 如果在调用 acquire 方法的时候, 其他线程已经使用了这个互斥锁, 那么此时 acquire 方法会堵塞, 直到这个互斥锁释放后才能再次上诉. with : with 的作用就是自动给这个线程加上互斥锁,自动释放这个互斥锁 import threading g_number = 0 # 全局变量多个线程可以读写,传递数据 def func ( lock ) : global g_number # 尝试加锁 lock . acquire ( ) for i in range ( 1000000 ) : g

互斥和条件变量区别

限于喜欢 提交于 2019-12-21 12:04:01
互斥量(mutex)从本质上说是一把锁,在访问共享资源前对互斥量进行加锁,在访问完成后释放互斥量上的锁。对互斥量进行加锁以后,任何其他试图再次对互斥锁加锁的线程将会阻塞直到当前线程释放该互斥锁。如果释放互斥锁时有多个线程阻塞,所有在该互斥锁上的阻塞线程都会变成可运行状态,第一个变为运行状态的线程可以对互斥锁加锁,其他线程将会看到互斥锁依然被锁住,只能回去再次等待它重新变为可用。 条件变量(cond)是在多线程程序中用来实现”等待–》唤醒”逻辑常用的方法。条件变量利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起;另一个线程使“条件成立”。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。线程在改变条件状态前必须首先锁住互斥量,函数pthread_cond_wait把自己放到等待条件的线程列表上,然后对互斥锁解锁(这两个操作是原子操作)。在函数返回时,互斥量再次被锁住。 第一点,首先我们要理解条件变量的作用是在等待某个条件达成时自身要进行睡眠或阻塞,避免忙等待带来的不必要消耗,所以条件变量的作用在于同步。条件变量这个变量其实本身不包含条件信息,条件的判断不在pthread_cond_wait函数功能中,而需要外面进行条件判断。这个条件通常是多个线程或进程的共享变量,这样就很清楚了

C#多线程间的同步问题

假装没事ソ 提交于 2019-12-21 01:12:10
使用线程时最头痛的就是共享资源的同步问题,处理不好会得到错误的结果,C#处理共享资源有以下几种: 1、lock锁 需要注意的地方: 1).lock不能锁定空值某一对象可以指向Null,但Null是不需要被释放的。(请参考:认识全面的null) 2).lock不能锁定string类型,虽然它也是引用类型的。因为字符串类型被CLR“暂留” 这意味着整个程序中任何给定字符串都只有一个实例,就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本。因此,只要在应用程序进程中 的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例。因此,最好锁定不会被暂留的私有或受保护成员。 3).lock锁定的对象是一个程序块的内存边界 4).值类型不能被lock,因为前文标红字的“对象被释放” ,值类型不是引用类型的 5).lock就避免锁定public 类型或不受程序控制的对象。 应用场景:经常会应用于防止多线程操作导致公用变量值出现不确定的异常,用于确保操作的安全性 2、 互斥锁(Mutex) 互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它。 互斥锁可适用于一个共享资源每次只能被一个线程访问的情况 我们可以把Mutex看作一个出租车,乘客看作线程。乘客首先等车,然后上车,最后下车。当一个乘客在车上时,其他乘客就只有等他下车以后才可以上车。而