信号量

线程同步---信号量

会有一股神秘感。 提交于 2019-12-05 22:57:31
信号量:   多线程环境下使用的同步设施,相当于是互斥锁的升级版本。互斥锁类似一个二元的信号量,确保一个线程能够独占一块资源, 信号量则通过一个计数器来控制线程对于共享资源的访问,当计数器的值大于0的时候线程可以访问共享资源,并且使得计数器的值 减1,当计数值变为0时,所有试图通过信号量的线程均会阻塞,直到计数器的值大于0。   信号量的函数:   int sem_init(sem_t*sem,int pshared,unsigned int value),该函数用于初始化一个信号量,第二个参数为0表示该信号量为当前 进程的局部信号量,否则该信号量在多个进程之间共享。   int sem_destory(sem_t* sem),用于销毁一个信号量。   int sem_wait(sem_t* sem),以原子操作的方式将信号量的值减1,如果信号量的值为0,则该操作将被阻塞到信号量具有非0的值。   int sem_trywait(sem_t* sem),相当图try_wait的非阻塞版本,当信号为0时该函数为-1,并设置errno为-1.   sem_post(sem_t* sem),以原子操作的方式将信号量的值加1,阻塞与sem_wait()的线程将会被唤醒。    以上的所有函数执行成功的返回值均为0,失败的返回值为-1,并且设置errno。    来源: https:/

python并发——信号量

怎甘沉沦 提交于 2019-12-05 17:30:44
信号量通常用于保护数量有限的资源,例如数据库服务器。在资源数量固定的任何情况下,都应该使用有界信号量。在生成任何工作线程前,应该在主线程中初始化信号量。 工作线程生成后,当需要连接服务器时,这些线程将调用信号量的 acquire 和 release 方法: 使用有界信号量能减少这种编程错误:信号量的释放次数多于其请求次数。 from threading import BoundedSemaphore maxconnections = 5 pool_sema = BoundedSemaphore(value=maxconnections) with pool_sema: conn = connectdb() try: do_some() finally: conn.close() 来源: https://www.cnblogs.com/wangbin2188/p/11937111.html

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

為{幸葍}努か 提交于 2019-12-05 15:59:24
基本概念简述 多个线程同时访问一个共享数据,很可能造成恶劣的后果;为了保证数据访问资源的正确性和安全性,需要对线程进行"同步" (Linux下所有的执行实体都称为任务(task),每个任务类似于单线程的进程,共享了同一个内存空间的多个任务构成了一个进程) 同步 指在一个线程对数据访问未结束的时候,其他线程不得访问同一个数据,将对数据的访问原子化 原子操作 不可分割,不会被线程调度打断的操作 (一个程序在运行的过程中可能被优先级更高的线程中断,而有些操作是不可中断的,不然会出现无法还原的后果,这时候操作系统就需要原子操作) 线程同步 同步最常用的方式"锁",每一个线程访问数据或资源前首先要获取锁,并在访问结束后释放锁;在锁被占用时试图获取锁,线程会进入等待,直到锁重新可用 二元信号量是最简单的一种锁,适合被一个线程独占访问的资源。它只有两种状态,占用和非占用;当一个线程获取锁后,其他线程试图获取锁将进入等待,直到该锁被释放。 互斥量类似于二元信号量,资源同时只允许一个线程访问,不同的是信号量在整个系统中允许任何线程获取并释放,即信号量可以被系统中一个线程获取,然后由另一个线程释放它;而互斥锁要求哪个线程获取互斥量,这个线程就要负责释放这个锁,其他线程释放该互斥量是无效的 临界资源 一次仅允许一个进程访问的资源称为临界资源,通常用互斥量控制临界资源的访问 P(测试)/ V(增加)操作

Lab7:同步互斥

。_饼干妹妹 提交于 2019-12-05 07:30:37
并发进程的正确性 独立进程 不和其他进程共享资源或状态 确定性 -> 输入状态决定结果 可重现 -> 能够重现起始条件 调度顺序不重要 并发进程 在多个进程间有资源共享 不确定性 不可重现 并发进程的正确性 执行过程是不确定性和不可重现的 程序错误可能是间歇性发生的 并发的好处 共享资源 加速 模块化 同步问题 时间 A B 3:00 查看冰箱,没有面包 3:05 离开家去商店 3:10 到达商店 查看冰箱,没有面包了 3:15 购买面包 离开家去商店 3:20 到家,把面包放进冰箱 到达商店 3:25 购买面包 3:30 到家,把面包放进冰箱 解决 利用两个原子操作实现一个锁(lock) Lock.Acquire() 在锁被释放前一直等待,然后获得锁 如果两个线程都在等待同一个锁,并且同时发现锁被释放了,那么只有一个能够获得锁 breadlock.Acquire(); //进入临界区 if (nobread) { buy bread; //临界区 } breadlock.Release(); //退出临界区 进程的交互关系:相互感知程度 相互感知的程度 交互关系 进程间的影响 相互不感知(完全不了解其它进程的存在) 独立 一个进程的操作对其他进程的结果无影响 间接感知(双方都与第三方交互,如共享资源) 通过共享进行协作 一个进程的结果依赖于共享资源的状态 直接感知(双方直接交互

VxWin--KUKA Robot操作系统

南笙酒味 提交于 2019-12-05 06:45:20
VxWin是KUKA Robot 操作系统 由Vxworks和Win95 或WinXP构成,采用TCP/IP通讯 其中 VxWorks是一种嵌入式的实时操作系统,所谓嵌入式系统就是用户自己开发设计板子,板子上通常有一颗CPU,VxWorks支持32位的 CPU,包括Intel公司的x86、Motorola公司的68k和PowerPC、MIPS、ARM、Intel公司的i960、Hitachi公司 的SH。我们设计的这块板子通常没有软件的自开发能力,所以我们需要一台通用机来辅助开发,这台通用机可以是PC或工作站,我们称辅助我们软件开发的通用 机为宿主机(Host),用户自己开发的板子为目标机(Target)。宿主机上要有一个集成开发环境(IDE)来辅助我们的软件开发,这套集成开发环境 可以运行在Windows95/NT或 UNIX下,包括交叉编译器(Cross Compiler)和交叉调试器(Cross Debugger),所谓交叉编译器就是在宿主机上编译生成可以在目标机上运行的代码IMAGE,交叉调试器就是通过宿主机和目标机之间的某种耦合方式实 现前后台调试。我们称宿主机上的这套集成开发环境为Tornado,编译生成的目标机上的可执行代码IMAGE为VxWorks。在系统安装的时候,集成 调试环境和VxWorks的原材料(一些obj文件)都安装到宿主机上

[20191119]探究ipcs命令输出2.txt

*爱你&永不变心* 提交于 2019-12-05 00:09:32
[20191119]探究ipcs命令输出2.txt --//继续上午的测试:http://blog.itpub.net/267265/viewspace-2664758/=>[20191119]探究ipcs命令输出.txt --//先补充ipcs 剩余2个参数 -l -u --//-l limits --//-u summary $ ipcs -l ------ Shared Memory Limits -------- max number of segments = 4096 max seg size (kbytes) = 67108864 max total shared memory (kbytes) = 17179869184 min seg size (bytes) = 1 ------ Semaphore Limits -------- max number of arrays = 128 max semaphores per array = 2600 max semaphores system wide = 332800 max ops per semop call = 2600 semaphore max value = 32767 ------ Messages: Limits -------- max queues system wide = 32768

go sync.WaitGroup源码分析

ぃ、小莉子 提交于 2019-12-04 23:37:14
go版本 :1.10.3 原理实现:信号量 信号量是Unix系统提供的一种保护共享资源的机制,用于防止多个线程同时访问某个资源。 可简单理解为信号量为一个数值: 当信号量>0时,表示资源可用,获取信号量时系统自动将信号量减1; 当信号量==0时,表示资源暂不可用,获取信号量时,当前线程会进入睡眠,当信号量为正时被唤醒 WaitGroup的定义 type WaitGroup struct { noCopy noCopy // noCopy用来标记不可复制,只能用指针传递,保证全局唯一.其实即使复制了,编译,运行都没问题,只有用go vet检测时才会显示出错误 // 只需要64位,即8个字节,其中高32位是counter值,低32位值是waiter值 // 不直接使用uint64,是因为uint64的原子操作需要64位系统,而32位系统下,可能会出现崩溃 // 所以这里用byte数组来实现,32位系统下4字节对齐,64位系统下8字节对齐,所以申请12个字节,其中必定有8个字节是符合8字节对齐的,下面的state()函数中有进行判断 state1 [12]byte sema uint32 // 信号量 } // 得到counter值(uint64的高32位),waiter值(uint64的低32位) func (wg *WaitGroup) state() *uint64 { //

并发和竞态

十年热恋 提交于 2019-12-04 18:26:22
(一)基本概念 对并发的管理是操作系统编程领域中的核心问题之一。 设备驱动程序开发者必须在开始设计时就考虑到并发因素,并对内核提供的并发管理机制有深刻的认识。 竞态:竞争状态; 引发竞态的原因是:并发式访问同一共享资源: ①多线程并发访问; ②抢占式并发访问; ③中断程序并发访问; ④SMP(Symmetric Multi-Processing)核间并发访问; 竞态造成的影响:处于竞态中的任务,所获得资源与预期不符,从而产生非预期的结果。 设计驱动程序的规则: ①尽可能避免资源共享,最明显的应用就是避免使用全局变量; ②在单个执行线程之外共享硬件或者软件资源的任何时候,必须显式地管理对该资源的访问,确保一次只有一个执行线程可操作共享资源; ③当内核代码创建了一个可能和内核的其他部分共享的对象时,该对象必须在还有其他组件引用自己时保持存在并正确工作;在对象还不能正确工作时,不能将其对内核可用; (二)信号量和互斥体 信号量分为:计数型信号量和二值信号量,二值信号量也称作互斥体。 目的:建立临界区,确保在任意时刻,临界区只被一个任务访问。 一个信号量的本质就是一个整数,它和一对函数联合使用,这对函数通常被称为P和V。 Linux内核中几乎所有的信号量均用户互斥。(因此,只要知道,计数型信号量的原理与停车场相似即可。) 如果在拥有一个信号量时发生错误

Operating System: Semaphore

亡梦爱人 提交于 2019-12-04 17:53:31
本文主要参考《计算机操作系统(第四版)》(西安电子科技大学出版社)以及清华大学操作系统公开课(向勇、陈渝),整理操作系统的基本概念,供自己复习查阅。 信号量机制 进程控制中最重要的一部分便是协调好进程的并发,控制进程同步,最具体的体现就是处理临界资源。信号量机制便广泛应用在临界资源处理方面。 信号量的分类与发展 信号量最初的定义是表示资源的 数目 。 整型信号量 顾名思义,这种信号量就是用一个整型量s表示某临界资源的数目。在初始化时,把s初始化为资源的数目,并限制只能通过原子操作 wait(s) 和 signal(s) 来访问,这两个操作通常也被称为 P 、 V 操作。可代码表示如下: wait(s) { while(s <= 0); --s; } signal(s) { ++s; } 记录型信号量 可以看到,在整型信号量中,只要申请不到资源,就会不断调试,并不符合“让权等待”原则(即让进程处于“忙等”状态),而记录型信号量就可以解决这个问题。 在记录型信号量中,简单的整型量s被扩充为记录型结构体,里面额外保存了一个进程表指针,用于链接所有等待进程。 struct ProcessControlBlock; using PCB = ProcessControlBlock; struct Semaphore { int value; // 资源数目 PCB* processList;

Java线程--Semaphore使用

北城余情 提交于 2019-12-04 15:48:28
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11872132.html Java线程--Semaphore使用 Semaphore是信号量, 也叫许可证管理器, 类似于取票窗口, 办事窗口, 打饭窗口等等这种情况, 只有排队等到了这样才算拿到了信号量, 拿到了许可证 . package concurrent.semaphore; import java.util.concurrent.Semaphore; /** * 信号量 , 许可证管理器 main 测试类 */ public class MainTest { public static void main(String[] args) throws InterruptedException { /** * 定义2个取票窗口, 公平的排队取票 */ Semaphore ticketWindow = new Semaphore(2, true); Thread[] threads = new Thread[10]; for (int i = 0 ; i < 30; i++) { /** * 前面十个小伙伴坚持排队 */ if (i < 10) { new Thread(new Man("坐火车良民" + i, ticketWindow, 0)).start(); }