互斥锁

队列、进程互斥锁、线程

徘徊边缘 提交于 2019-12-01 23:27:25
目录 1.进程的并行和并发 2.并行和并发的区别 3.进程互斥锁 4.队列 4.1multiprocess.Queue介绍 4.2 IPC进程间通信实例1 4.3 ICP通信实例2:生产者与消费者模型 5.线程 5.1什么是线程? 5.2 使用线程的实际场景 5.3 内存中的线程 5.4用户级线程和内核级线程(了解) 5.5 用户级与内核级线程的对比 5.6 混合实现 5.7 GIL全局解释器锁 5.8 开启线程的两种方式 5.9 线程对象的属性 5.10 线程互斥锁 1.进程的并行和并发 并行: 并行是指两者同时执行,比如赛跑,两个人都在不停的往前跑;(资源够用,比如三个线程,四核的CPU ) 并发: 并发是指资源有限的情况下,两者交替轮流使用资源,比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A ,交替使用,目的是提高效率。 2.并行和并发的区别 并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,这就要求必须有多个处理器。 并发是从宏观上,在一个时间段上可以看出是同时执行的,比如一个服务器同时处理多个session。 3.进程互斥锁 作用:让加锁的部分由并发变成串行,牺牲了执行效率,保证了数据安全。 应用:在程序使用同一份数据时,就会引发数据安全和数据混乱等问题,需要使用锁来维持数据的顺序取用。 下面的小程序模拟抢票软件

(day29) 进程互斥锁 + 线程

ぐ巨炮叔叔 提交于 2019-12-01 23:23:26
目录 进程互斥锁 队列和堆栈 进程间通信(IPC) 生产者和消费者模型 线程 什么是线程 为什么使用线程 怎么开启线程 线程对象的属性 线程互斥锁 进程互斥锁 进程间数据不共享,但是共享同一套文件系统, 互斥锁:让并发变成串行,牺牲了执行效率,保证了数据安全 应用:在程序并发执行时,需要修改数据时使用 # data(json文件) {"target":1} # 模拟抢票功能.py import json import time from multprocessing import Process from multprocessing import Lock # 查看余票 def search(user): # 打开json文件查看余票 with open('data','r',encoding = 'utf-8')as f: dic = json.load(f) print(f'{user}查看余票:{dic.get("ticket")}') def buy(user): # 先打开车票数据 with open('data','r',encoding = 'utf-8')as f: dic = json.load(f) # 模拟网络延迟 time.sleep(1) # 若有票,修改data数据 if dic.get("ticket") > 0: dic['ticket'] -=

并发编程

情到浓时终转凉″ 提交于 2019-12-01 22:55:43
目录 并发编程 互斥锁 : 队列: 生产者与消费者: 并发编程 互斥锁 : 进程数据不共享,但是共享同一套文件系统; 同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱 互斥锁的意思就是互相排斥,如果把多个进程比喻为多个人,互斥锁的工作原理就是多个人都要去争抢同一个资源 互斥锁的原理,就是把并发改成穿行,降低了效率,但保证了数据安全不错乱 from multiprocessing import Process,Lock import os , time def wprk(lock): lock.acquire() #枷锁 print(f'{os.getpid} is running') time.sleep(2) print(f'{os.getpid} is done') lock.release() #开锁 if __name__ == '__main__': lock =Lock() for i in range(3): P = Process(target = work,args=(lock,)) p.start() 并发运行,效率高,但竞争写同一文件,数据写入错乱 加锁处理:由并发变成了串行,牺牲了运行效率,但保证了数据安全 使用join将并发改成穿行,确实能保证数据安全,但问题是连查票操作也变成只能一个一个人去查了

go 安全map 实现, 互斥锁和读写锁

大憨熊 提交于 2019-12-01 21:38:08
###互斥锁 其中Mutex为互斥锁,Lock()加锁,Unlock()解锁,使用Lock()加锁后,便不能再次对其进行加锁,直到利用Unlock()解锁对其解锁后,才能再次加锁.适用于读写不确定场景,即读写次数没有明显的区别,并且只允许只有一个读或者写的场景,所以该锁叶叫做全局锁. package main import ( "fmt" "sync" "errors" ) type MyMap struct { mp map[string]int mutex *sync.Mutex } func (this *MyMap) Get(key string) (int, error) { this.mutex.Lock() i, ok := this.mp[key] this.mutex.Unlock() if !ok { return i, errors.New("不存在") } return i, nil } func (this *MyMap) Set(key string, v int) { this.mutex.Lock() defer this.mutex.Unlock() this.mp[key] = v } func (this *MyMap) Display() { this.mutex.Lock() defer this.mutex.Unlock() for k

【TencentOS tiny】深度源码分析(6)——互斥锁

…衆ロ難τιáo~ 提交于 2019-12-01 13:45:14
互斥锁 互斥锁又称互斥互斥锁,是一种特殊的信号量,它和信号量不同的是,它具有 互斥锁所有权、递归访问以及优先级继承 等特性,在操作系统中常用于对临界资源的 独占式 处理。在任意时刻互斥锁的状态只有两种, 开锁或闭锁 ,当互斥锁被任务持有时,该互斥锁处于闭锁状态,当该任务释放互斥锁时,该互斥锁处于开锁状态。 一个任务持有互斥锁就表示它拥有互斥锁的所有权,只有该任务才能释放互斥锁,同时其他任务将不能持有该互斥锁,这就是互斥锁的 所有权 特性。 当持有互斥锁的任务再次获取互斥锁时不会被挂起,而是能递归获取,这就是互斥锁的 递归访问 特性。这个特性与一般的信号量有很大的不同,在信号量中,由于已经不存在可用的信号量,任务递归获取信号量时会发生挂起任务最终形成 死锁 。 互斥锁还拥有 优先级继承 机制,它可以将 低 优先级任务的优先级 临时提升 到与获取互斥锁的 高 优先级任务的优先级 相同 ,尽可能 降低 优先级翻转的危害。 在实际应用中,如果想要实现同步功能,可以使用信号量,虽然互斥锁也可以用于任务与任务间的同步,但互斥锁更多的是用于临界资源的互斥访问。 使用互斥锁对临界资源保护时,任务必须先获取互斥锁以获得访问该资源的所有权,当任务使用资源后,必须释放互斥锁以便其他任务可以访问该资源(而使用信号量保护临界资源时则可能发生优先级翻转,且 危害 是不可控的)。 优先级翻转

线程中的多线程、并行和并发、同步和异步、阻塞和非阻塞、线程安全

泪湿孤枕 提交于 2019-12-01 12:34:23
多线程 :指的是这个程序(一个进程)运行时产生了不止一个线程 并行与并发: 并行 :多个 cpu 实例或者多台机器同时执行一段处理逻辑,是真正的同时。 并发 :通过 cpu 调度算法,让用户看上去同时执行,实际上从 cpu 操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用 TPS 或者 QPS 来反应这个系统的处理能力。 线程安全 :经常用来描绘一段代码。指在并发的情况之下,该代码经过多线程使用, 线程的调度顺序不影响任何结果 。这个时候使用多线程,我们只需要关注系统的内存, cpu 是不是够用即可。反过来,线程不安全就意味着线程的调度顺序会影响最终结果 同步 : Java 中的同步指的是通过人为的控制和调度,保证共享资源的多线程访问成为线程安全,来保证结果的准确。 同步 :就是指在一个线程访问一个数据还未结束的时候,其他线程不能对该数据进行访问,即将该数据的访问原子化。 同步 : 发送一个请求 , 等待返回 , 然后再发送下一个请求 异步 : 发送一个请求 , 不等待返回 , 随时可以再发送下一个请求 锁 :即为同步处理的常见方法。它是一种非强制机制,一个线程在访问数据或资源前要先获取锁,在访问结束后释放锁。如果在获取时该锁已被占用,则等待锁直到该锁被释放。 同步和异步 同步就是烧开水,需要自己去轮询(每隔一段时间去看看水开了没)

Java并发:线程安全与锁优化

时间秒杀一切 提交于 2019-12-01 11:07:08
概述 人们很难想象现实中的对象在一项工作进行期间,会被不停地中断和切换,对象的属性(数据)可能会在中断期间被修改和变“脏”,而这些事情在计算机世界中则是很正常的事情。有时候,良好的设计原则不得不向现实做出一些让步,我们必须让程序在计算机中正确无误地运行,然后再考虑如何将代码组织得更好,让程序运行更快。对于“高效并发”来说,首先需要保证并发的正确性,然后在此基础上实现高效。 1.线程安全 《Java Concurrency In Practice》的作者Brian Goetz对“线程安全”有一个比较恰当的定义:“当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果,那这个对象是线程安全的”。 这个定义比较严谨,它要求线程安全的代码都必须具备一个特征:代码本身封装了所有必要的正确性保障手段(如互斥同步等),令调用者无须关心多线程的问题,更无须自己采取任何措施来保证多线程的正确调用。这点听起来简单,但其实并不容易做到,在大多数场景中,我们都会将这个定义弱化一些,如果把“调用这个对象的行为”限定为“单次调用”,这个定义的其他描述也能够成立的话,我们就可以称它是线程安全了。 1.1 Java语言中的线程安全 按照线程安全的“安全程度”由强至弱来排序

互斥锁,信号量,条件变量,读写锁

*爱你&永不变心* 提交于 2019-12-01 10:19:05
互斥锁 互斥锁的特性: 1. 原子性:当有一个线程成功拿到了这个锁,其他线程都无法在相同的时间拿到这个锁 2. 唯一性:在一个线程拿到锁的这段时间,只有当这个线程把锁释放掉,其他的线程才有可能拿到 3. 非繁忙等待性:如果一个线程已经锁定了一个互斥量,第二个线程又视图去拿到这个锁的前线,则第二个锁将被挂起,等待第一个线程对互斥量解锁位置,同时第二个线程获取锁,继续往下执行 pthread_mutex_init pthread_mutex_lock pthread_mutex_trylock pthread_mutex_unlock pthread_mutex_destroy 信号量 信号量相当于一个加强版的互斥锁,提高了共同访问共享资源的线程数目(从串行,变成了并行) sem_init sem_wait sem_trywait sem_post sem_getvalue sem_destroy 条件变量 自动阻塞一个线程,直到某种特殊的情况发生为止,通常条件变量和互斥锁相互配合使用。 条件变量使得我们可以睡眠等待某种条件出现,条件变量是利用线程间共享的全局变量进行同步的一个机制。 条件变量主要包括两个动作: 1. 一个线程等待 “条件变量的成立“ 2. 另一个线程使得 “条件成立” 条件变量的作用: 1. 先把调用线程放到等待条件的队列上 2. 释放指定的锁以提供其他线程添加任务

2-6 GIL全局解释器锁

江枫思渺然 提交于 2019-12-01 06:46:48
一 引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) 结论:在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。>有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL

1-5 互斥锁

余生长醉 提交于 2019-12-01 06:42:58
一 互斥锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如下 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('%s is done' %os.getpid()) if __name__ == '__main__': for i in range(3): p=Process(target=work) p.start() 如何控制,就是加锁处理。而互斥锁的意思就是互相排斥,如果把多个进程比喻为多个人,互斥锁的工作原理就是多个人都要去争抢同一个资源:卫生间,一个人抢到卫生间后上一把锁,其他人都要等着,等到这个完成任务后释放锁,其他人才有可能有一个抢到......所以互斥锁的原理,就是把并发改成穿行,降低了效率,但保证了数据安全不错乱 #由并发变成了串行,牺牲了运行效率,但避免了竞争 from multiprocessing import Process,Lock import os,time def work(lock): lock.acquire(