信号量

内核同步-锁机制

好久不见. 提交于 2019-12-09 20:44:18
在 Linux 系统上,多个进程可以同时运行,以及各种中断发生的中断也在同时得到处理,这种多个上下文宏观上同时运行的情况称为并发。并发具体包括如下几种可能: 1) UP平台上,一个进程正在执行时被另一个进程抢占; 2) UP平台上,一个进程正在执行时发生了中断,内核转而执行中断处理程序; 3) SMP平台上,每个处理器都会发生 UP 平台上的情况; 4) SMP平台上,多个进程或中断同时在多个 CPU 上执行; 多个并发的上下文同时使用同一个资源的情况称为竞态,而可能发生竞态的这一段代码称为临界区。内核编程时的临界区,比较多的情况是: 1) 代码访问了全局变量,并且这段代码可被多个进程执行; 2) 代码访问了全局变量,并且这段代码可被进程执行,也可被中断处理程序执行; 针对上述情况,内核提供了如下手段来解决竟态问题: 1)锁机制: 2)院子操作: 下面会先介绍锁机制。 Linux内核提供了多种锁机制,这些锁机制的区别在于,当获取不到锁时,执行程序是否发生睡眠并进行系统调度。具体包括自旋锁、互斥体、信号量。 一、自旋锁:spinlock_t 自旋锁有两个基本操作:获取与释放。获取自旋锁时,当判断锁的状态为未锁,则会马上加锁,如果已经是锁定的状态,当期执行流程则会执行“忙等待”,中间没有任何的调度操作。也就说执行流程从判断锁的状态到完成加锁,是一个原子操作,在执行上是不可分割的。

第15章 进程间通行 15.6 XSI IPC 15.7 消息队列

北战南征 提交于 2019-12-09 20:35:47
15.6 XSI IPC (1)3种称作XSI IPC的IPC是: 1)消息队列 2)信号量 3)共享存储器 (2)标识符和键 1)标识符:是一个非负整数,用于引用IPC结构。是IPC对象的内部名。 2)键:IPC对象的外部名。可使多个合作进程能够在同一IPC对象上汇聚。 (3)IPC_PRIVATE键: 用于创建一个新的IPC结构。不能指定此键来引用一个现有的IPC结构。 (4)ftok函数: 由一个路径名和项目ID产生一个键。 (5)ipc_perm结构体 规定了ipc结构的权限和所有者。 (6)结构限制: XSI IPC结构都有内置限制,可通过重新配置内核来改变。 1)sysctl命令:观察、修改内核配置参数。 2)ipcs -l:显示ipc相关限制。 (7)IPC结构和管道、FIFO的区别: IPC结构在系统范围内起作用,且没有引用计数。 (8)IPC结构在文件系统中没有名字;IPC不使用文件描述符。 15.7 消息队列 (1)新的应用程序中不要使用消息队列。它们有缺点。(15.6.4) (2)客户进程和服务器进程之间的双向数据流,可以使用消息队列或全双工管道。 15.8 信号量 (1)多个进程间共享一个资源,可以使用信号量、记录锁和互斥量中的一种来协调。 (2)共享存储中的互斥量速度最快,但作者依然喜欢使用记录锁的两个原因: 1)<459> 2) <459> 15.9

spinlock与linux内核调度的关系

烈酒焚心 提交于 2019-12-09 20:22:18
作者: 刘洪涛, 华清远见嵌入式学院 高级讲师,ARM公司授权ATC讲师。 关于自旋锁用法介绍的文章,已经有很多,但有些细节的地方点的还不够透。我这里就把我个人认为大家容易有疑问的地方拿出来讨论一下。 一、自旋锁(spinlock)简介 自旋锁在同一时刻只能被最多一个内核任务持有,所以一个时刻只有一个线程允许存在于临界区中。这点可以应用在多处理机器、或运行在单处理器上的抢占式内核中需要的锁定服务。 二、信号量简介 这里也介绍下信号量的概念,因为它的用法和自旋锁有相似的地方。 Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。 三、自旋锁和信号量对比 在很多地方自旋锁和信号量可以选择任何一个使用,但也有一些地方只能选择某一种。下面对比一些两者的用法。 表1-1自旋锁和信号量对比 应用场合 信号量or 自旋锁 低开销加锁(临界区执行时间较快) 优先选择 自旋锁 低开销加锁(临界区执行时间较长) 优先选择 信号量 临界区可能包含引起睡眠的代码 不能选自旋锁,可以选择 信号量 临界区位于非进程上下文时,此时不能睡眠 优先选择 自旋锁 ,即使选择信号量也只能用 down_trylock 非阻塞的方式

进程间、线程间通信方式

偶尔善良 提交于 2019-12-09 20:14:19
一、进程间的通信方式 (1)管道( pipe ) :管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 (2)有名管道 (namedpipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。 (3) 信号量(semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 (4) 消息队列( messagequeue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 (5) 信号 (sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。 (6) 共享内存(shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。 (7) 套接字(socket ) : 套解口也是一种进程间通信机制

操作系统 Linux操作系统编程开发

♀尐吖头ヾ 提交于 2019-12-08 05:12:37
Linux操作系统编程开发 预备知识:   1、进程操作:Linux系统是 多任务的操作系统 ,采用 进程 作为 任务调度的单位, 进程在Linux系统下的概念是程序代码的一次执行,包括运行的代码和运行需要的数据、参数等资源。   2、进程和程序的区别:一方面:在Linux系统下,进程是程序代码的执行,所以程序是一段运行的,有生命力的程序,是一个动态的概念;一个程序是指储存在磁盘或者其他存储介质中的静态代码。另一方面:一个进程是基于一个程序运行的,而一个程序可以被重复载入到内存,形成多个进程!   3、 CPU时间片(Linux系统大约1ms) :时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。   4、Linux系统中进程在宏观上是并行,在微观上是串行的(一个CPU)。 在宏观上是并行 :同时可以打开多个进程;每个进程都有一个时间片和优先级。 在微观上是串行 :在每一个CPU时间片中,每个进程都有机会运行,优先级高的进程被运行的概率更大。如果时间片结束,进程还在运行,CPU将剥夺并分配给另一个进程;如果进程在时间片结束之前结束或者进入阻塞状态,CPU立即进行切换!一个CPU,一次只能执行程序的一部分。   5、mmu和多进程系统:   6、PID(进程号Process ID):在Linux系统中,每个进程都有一个 进程号

JAVA多线程--信号量(Semaphore)

独自空忆成欢 提交于 2019-12-07 09:46:46
简介 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。 一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。拿到信号量的线程可以进入代码,否则就等待。通过acquire()和release()获取和释放访问许可。 概念 Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。 以一个停车场运作为例。为了简单起见,假设停车场只有三个车位,一开始三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。 在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是信号量的作用。 更进一步,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程(车辆)都会将该整数减一(通过它当然是为了使用资源)

linux上的进程通信学习笔记

大城市里の小女人 提交于 2019-12-07 00:17:42
参考资料 <<精通Linux C编程>> http://man7.org/linux/man-pages/man2/open.2.html https://www.cnblogs.com/52php/p/5840229.html 在 Android中的Handler的Native层研究 文章中研究一下一把Linux中的匿名管道的通信机制,今天这里Linux中的进程间通信补齐。 在Linux中,实现进程通信的方法包括管道(匿名管道和具名管道),消息队列,信号量,共享内存,套接口等。消息队列,信号量,共享内存统称为系统的(POSIX和System V)IPC,用于本地间的进程通信,套接口(socket)则运用于远程进程通信。 各个通信机制定义如下: 匿名管道(Pipe)和具名管道(named pipe):匿名管道用于具有亲缘关系进程间的通信,具名管道克服了管道没有名字的限制,因此除了具有匿名管道的功能外,还允许在无亲缘关系的进程中进行通信。 消息队列(Message):消息队列为消息的链接表,包括POSIX消息队列和System V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读取队列中的消息。 共享内存:是的多个进程可以访问同一块内存空间,是最快的可以IPC形式。是针对其他的通信机制运行效率较低而设计出来的。往往与其他通信机制,如信号量结合使用

突然发现到今天已经很难找到对底层理解这么透彻的人

主宰稳场 提交于 2019-12-07 00:17:30
链接: http://blog.csdn.net/elssann/archive/2004/10/25/150088.aspx 原文: 在VC版的网络编程区,基本上每天都可以看到大量关于IOCP(完成端口)的帖子和讨论,很多人比较反感IOCP,特别是一些一直在UNIX下写程序的人。就我个人的看法来说,IOCP是一个设计得很巧妙的东西,是目前WINDOWS下编写高效IO程序的唯一选择。至少目前为止,我在UNIX下或者LINUX下都没看到类似的模型,就模型的先进性来说,我认为IOCP可能是领先的,问题在于WINDOWS的线程性能不够好,加上本质上是一个基于GUI的操作系统,别的方面劣势抵消了IOCP带来的优势,比如WINDOWS下的线程切换速度就没LINUX下快,这是因为WINDOWS下定时的时间精度所确定的。 IOCP从本质上来说,没什么复杂的,抛开异步IO(这个是系统本身的IO,至少我没法实现),我们可以自己设计一个类似这样的东西,而且非常之简单。用过IOCP的人都应该熟悉这两个函数:PostQueueCompletionStatus, GetQueueCompletionStatus。用第一个函数Post给IOCP的数据,可以用第二个函数Get出来,其实我们就可以用一个信号量加一个队列和一个临界区就可以实现,队列为空的时候,信号量为0

多进程共享内存

瘦欲@ 提交于 2019-12-06 21:24:25
问题描述 一个大小为3的缓冲区,初始为空 2个生产者随机等待一段时间,往缓冲区添加数据,若缓冲区已满,等待消费者取走数据后再添加,重复6次 3个消费者随机等待一段时间,从缓冲区读取数据,若缓冲区为空,等待生产者添加数据后再读取,重复4次 说明: 显示每次添加和读取数据的时间及缓冲区里的数据 生产者和消费者用进程模拟 思路 这道题目涉及到的知识点有: 进程控制管理,包括进程的创建与销毁等 进程通信技术,如管道、共享内存等 解决思路主要是: 一个主进程负责创建和销毁子进程,负责创建共享内存区和公用信号量 五个子进程,两个是生产者,三个是消费者,通过信号量对共享内存进行互斥读写 创建互斥访问量 创建信号量如下: 信号量:EMPTY, FILLED, RW 初始化:EMPTY=3,FILLED=0,RW=1 说明: EMPTY 信号量指示缓冲区有多少个空位置没有被占用,因此初始值等于缓冲区数量; FILLED 指示缓冲区有多少个位置被占用,因此初始值等于0; RW 指示是否允许对共享内存进行读写操作,为防止进程并发执行导致的数据共享错误,每次仅允许一个进程对共享内存进行操作,因此初始值为1. 生产者消费者执行操作 生产者 P(EMPTY);//首先询问是否有空闲缓冲区,没有则阻塞,等待消费者拿出数据释放一个缓冲区;有则EMPTY-=1 P(RW);//是否可以对共享内存进行读写操作

Windows API一日一练(47)CreateSemaphore和ReleaseSemaphore函数

时光毁灭记忆、已成空白 提交于 2019-12-06 17:38:45
在开发软件的过程中,多线程的程序往往需要实现相互通讯,比如几个线程添加一个消息到队列里,而另一个线程在睡眠时,就需要唤醒那个线程来处理事情。在这其中,就需要使用到信号量来进行同步。 CreateSemaphore 是创建信号量, ReleaseSemaphore 是增加信号量。 函数 CreateSemaphore 和 ReleaseSemaphore 声明如下: WINBASEAPI __out HANDLE WINAPI CreateSemaphoreA( __in_opt LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, __in LONG lInitialCount, __in LONG lMaximumCount, __in_opt LPCSTR lpName ); WINBASEAPI __out HANDLE WINAPI CreateSemaphoreW( __in_opt LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, __in LONG lInitialCount, __in LONG lMaximumCount, __in_opt LPCWSTR lpName ); #ifdef UNICODE #define CreateSemaphore CreateSemaphoreW