信号量

python多线程+GIL

╄→尐↘猪︶ㄣ 提交于 2019-11-28 07:29:04
---恢复内容开始--- python的多线程实际上只有一个线程。 了让各个线程能够平均利用CPU时间,python会计算当前已执行的微代码数量,达到一定阈值后就强制释放GIL。而这时也会触发一次操作系统的线程调度(当然是否真正进行上下文切换由操作系统自主决定)。 GIL全局解释器锁: 保证同一时间只有一个线程得到数据并且只有一个线程执行,但是cpu调度时间到了以后,第一个线程无论是否完成均程等待状态(若未执行完毕,数据放入寄存器中)下一线程得到的依旧是原始的公共数据。 用户级lock:保证同一时间只有一个线程在修改数据。(可以避免几个线程同时对公共原始数据进行修改,提高线程效率) 为公共数据Lock:一个线程修改后,释放,下一进程才可再次进行修改。 RLock(递归锁): 在一个大锁中还要再包含子锁 1 import threading, time 2 3 4 def run1(): 5 print("grab the first part data") 6 lock.acquire() 7 global num 8 num += 1 9 lock.release() 10 return num 11 12 13 def run2(): 14 print("grab the second part data") 15 lock.acquire() 16 global num2

第五章 信号量

℡╲_俬逩灬. 提交于 2019-11-28 05:52:07
简介: 信号量用来进行资源管理和任务同步。 FreeRTOS 中 信号量分为 二值信号量,互斥信号量,计数信号量和递归信号量。 二值信号量 官网介绍: https://www.freertos.org/Embedded-RTOS-Binary-Semaphores.html 一个只有一个队列项的队列。 可以用于互斥访问 或者 同步,常用于任务(中断)和任务间的同步。 函数 创建二值信号量 xSemaphoreCreateBinary() 释放信号量 xSemaphoreGive() 获取信号量 xSemaphoreTake() 计数信号量 官网介绍: https://www.freertos.org/Real-time-embedded-RTOS-Counting-Semaphores.html 简介: 计数信号量是长度大于1的队列。 一 个二值信号量最多只可以锁存一个中断事件。在锁存的事件还未被处理之前,如果还有中断事件发生,那么后续发生的中断事件将会丢失。如果 用计数信号量代替二值信号量,那么,这种丢中断的情形将可以避免。 常用与两个场合: 计算事件。 在这种使用场景中,事件处理程序将在每次事件发生时“给出”信号量(递增信号量计数值),并且处理程序任务将在每次处理事件时“获取”信号量(递减信号量计数值)。因此,计数值是已发生事件数与已处理数之间的差值。在这种情况下

进程间通信之-----信号量

我怕爱的太早我们不能终老 提交于 2019-11-28 03:40:49
进程间通信简单的说有三个问题,第一个问题是:一个进程如何把信息传递给另一个,第二个问题是:要确保两个或者更多的进程在互动中不会出现交叉(即是进程互斥问题),第三个问题是:进程间同步问题、 四种进程或者线程同步互斥的控制方法 1):临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。 2):互斥量:为协调共同对一个共享资源的单独访问而设计的 3):信号量:为控制一个具有有限数量用户资源而设计 4):事件:用来通知线程有一些事件已发生,从而启动后继任务的开始。 临界区(Critical Section)   保证在某一时刻只有一个线程能访问数据的简便办法,在任意时刻只允许一个线程对共享资源进行访问,如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开,临界区在被释放后,其他线程可以继续抢占,并以此达到原子方式操作共享资源的目的。   临界区包含两个操作原语: EnterCriticalSection() 进入临界区 LeaveCriticalSection() 离开临界区 虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。 互斥量(Mutex)   互斥量跟临界区很相似,只有拥有互斥量对象的线程才具有访问资源的权限,由于互斥对象只有一个

信号量与互斥锁

☆樱花仙子☆ 提交于 2019-11-28 03:40:25
信号量与普通整型变量的区别: ①信号量(semaphore)是非负整型变量,除了初始化之外,它只能通过两个标准原子操作:wait(semap) , signal(semap) ; 来进行访问; ②操作也被成为PV原语(P来源于Dutch proberen"测试",V来源于 Dutch verhogen"增加"),而普通整型变量则可以在任何语句块中被访问; 信号量与互斥锁之间的区别: 1. 互斥量用于线程的互斥,信号线用于线程的同步。 这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源 2. 互斥量值只能为0/1,信号量值可以为非负整数。 也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。 3. 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到。 信号量 信号量(Semaphore)

线程同步与锁

本小妞迷上赌 提交于 2019-11-28 03:40:13
二元信号量,多元信号量,互斥量,临界区。其它包括读写锁,条件变量。 -1:二元信号量,适合与只能被一个线程独占访问的资源。当二元信号量处于非占用状态时,第一个试图获取该二元信号量的线程会获得该锁,并将二元信号量重置为占用状态,在未释放该锁前,其它所有试图获取该二元信号量的线程将会等待。 -2:多元信号量,简称信号量。一个初始值为N的信号量允许N个线程并发访问。 获取该信号量时,信号量的值减一,当信号量的值小于0时,再来获取信号量的线程进入等待状态。 释放该信号量时,信号量的值加一,当信号量的值大于0时,唤醒一个处于等待中的线程。 -3:互斥量,与二元信号量类似,资源同时仅允许一个线程访问,但不同之处的是, 信号量在整个系统内可以被任意线程获取,释放。即信号量可以被线程A获取,再由线程B释放。而互斥量要求那个线程获取,哪个线程就要负责释放这个锁,其它线程去释放是无效的 。 -4:临界区,比互斥量更加严格的同步手段。 临界区与信号量,互斥量不同之处在于,信号量和互斥量在系统的任何进程中都是可见的,一个进程创建了互斥量,其它进程来获取该锁是合法的。临界区的作用范围仅限于本进程 。除此之外,互斥量和临界区具有相同的性质。 使用互斥量不仅能够在同一应用程序不同线程中实现资源的安全共享,而且可以在不同应用程序的线程之间实现对资源的安全共享。 来源: http://www.cnblogs.com

线程基础

。_饼干妹妹 提交于 2019-11-28 03:39:57
cpu:承担所有计算的任务 操作系统:是计算机的管理者,它负责任务调度,资源分配和管理,统领整个计算机硬件 应用程序:是某种功能的程序,程序运行于操作系统上 进程由: 程序, 数据集合 和 进程控制块 三部分组成 程序:用于描述进程要完成的功能,是控制进程执行的指令集。 数据集合:是程序在执行时所需要的数据和工作区 程序控制块:包含进程的描述信息和控制信息,是进程存在的唯一标识 每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。 进程是操作系统分配资源的最小单位,线程是程序执行的最小单位(线程出现的一个原因是进程间切换开销较大) 各个线程之间共享程序的内存地址(也就是进程所在的内存空间) 一个标准线程:线程ID,当前指令指针(PC),寄存器和堆栈组成 进程:内存空间(代码数据,进程空间,打开的文件)和一个或多个线程组成 进程与线程的资源共享关系 当线程的数量小于处理器的数量时,线程的并发是真正的并发,不同的线程运行在不同的处理器上,当线程的数量大于处理器的数量时,线程的并发会受到一些阻碍,此时不是真正的并发,因为此时至少有一个处理器会运行多个线程 频繁等待的线程:称为IO密集型线程 频繁进行大量计算以至于每次都把所有时间片全部耗尽,很少等待的线程:称为 CPU密集型线程 在优先级调度环境下,线程优先级的改变有三种方式 1.用户指定优先级 2

并发编程--并发编程框架概述

拟墨画扇 提交于 2019-11-28 01:44:06
JDK给我们提供了一个并发编程的包java.util.current,并发编程包中是锁功能更加强大,并且他允许更灵活的使用锁。 JUC包中的锁,包括:Lock接口,ReadWriteLock接口,LockSupport阻塞原语,Condition条件,AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer三个抽象类,ReentrantLock独占锁,ReentrantReadWriteLock读写锁。由于CountDownLatch,CyclicBarrier和Semaphore也是通过AQS来实现的;因此,我也将它们归纳到锁的框架中进行介绍。 先看看锁的框架图,如下所示。 1、Lock接口 JUC包中的 Lock 接口支持那些语义不同(重入、公平等)的锁规则。所谓语义不同,是指锁可是有"公平机制的锁"、"非公平机制的锁"、"可重入的锁"等等。"公平机制"是指"不同线程获取锁的机制是公平的",而"非公平机制"则是指"不同线程获取锁的机制是非公平的","可重入的锁"是指同一个锁能够被一个线程多次获取。 2、ReadWriteLock读写锁接口 ReadWriteLock 接口以和Lock类似的方式定义了一些读取者可以共享而写入者独占的锁。JUC包只有一个类实现了该接口

计算机操作系统 - 进程管理

牧云@^-^@ 提交于 2019-11-27 23:54:11
进程与线程 1. 进程 2. 线程 3. 区别 进程状态的切换 进程调度算法 1. 批处理系统 2. 交互式系统 3. 实时系统 进程同步 1. 临界区 2. 同步与互斥 3. 信号量 4. 管程 经典同步问题 1. 读者-写者问题 2. 哲学家进餐问题 进程通信 1. 管道 2. FIFO 3. 消息队列 4. 信号量 5. 共享存储 6. 套接字 进程与线程 1. 进程 进程是资源分配的基本单位。 进程控制块 (Process Control Block, PCB) 描述进程的基本信息和运行状态,所谓的创建进程和撤销进程,都是指对 PCB 的操作。 下图显示了 4 个程序创建了 4 个进程,这 4 个进程可以并发地执行。 2. 线程 线程是独立调度的基本单位。 一个进程中可以有多个线程,它们共享进程资源。 QQ 和浏览器是两个进程,浏览器进程里面有很多线程,例如 HTTP 请求线程、事件响应线程、渲染线程等等,线程的并发执行使得在浏览器中点击一个新链接从而发起 HTTP 请求时,浏览器还可以响应用户的其它事件。 3. 区别 Ⅰ 拥有资源 进程是资源分配的基本单位,但是线程不拥有资源,线程可以访问隶属进程的资源。 Ⅱ 调度 线程是独立调度的基本单位,在同一进程中,线程的切换不会引起进程切换,从一个进程中的线程切换到另一个进程中的线程时,会引起进程切换。 Ⅲ 系统开销

进程_线程 之(四) --- 信号量

眉间皱痕 提交于 2019-11-27 21:53:32
信号量 信号量:   信号量就对线程最大并发数做限制,   如果当前线程开启的个数超过了线程最大并发量,   超出的线程要暂停执行,直到有线程执行完成,才加入新的线程 代码 1 import threading 2 from time import sleep 3 4 # 定义一个信号量(线程的最大并发量) 5 sem = threading.Semaphore(2) # 允许2个线程并发执行 6 7 def func(): 8 with sem: # 设置并发量。防止并发访问亮过载,影响服务器 9 print("当前线程%s正在执行..."%threading.current_thread().name) 10 sleep(2) 11 print("当前线程%s执行结束"%threading.current_thread().name) 12 13 if __name__ == '__main__': 14 for _ in range(5): # 开启五个线程 15 t = threading.Thread(target=func) 16 t.start() 结果 1 结果: 2 """ 3   当前线程Thread-1正在执行... 4   当前线程Thread-2正在执行... 5   当前线程Thread-1执行结束 6   当前线程Thread-2执行结束 7  

GCD的使用总结

为君一笑 提交于 2019-11-27 21:40:50
什么是多线程? 计算机在运行一段程序的时候,会把该程序的CPU命令列配置到内存中,然后按照顺序一个一个执行命令列,这样1个CPU执行的CPU命令列为一条无分叉路径就是线程。 而有多条这样的执行指令列的路径存在时即为多线程。 iOS实现多线程有4种方法: pthreads NSThread GCD NSOperation & NSOperationQueuef 这里我们主要讲GCD 一、Dispatch Queue和线程的关系 什么是Dispatch Queue? 如其名称,是执行处理的等待队列。当我们通过dispatch_async等函数把Block加入Dispatch Queue后,Dispatch Queue按照追加的顺序(FIFO)执行处理。 通过Dispatch Queue执行处理 Dispatch Queue的种类 Serial Dispatch Queue(串行队列) ——等待现在执行中处理结束再加入队列 Concurrent Dispatch Queue(并发队列) ——不等待现在执行中处理结束,直接加入队列 Serial Dispatch Queue Concurrent Dispatch Queue 用代码说明: Serial Dispatch Queue dispatch_queue_t serial_queue = dispatch_queue_create(