linux信号量

线程同步(互斥锁与信号量的作用与区别)

感情迁移 提交于 2020-03-28 03:59:40
“信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作(大家都在semtake的时候,就阻塞在 哪里)。而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用的” 也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。而线程互斥量则是“锁住某一资源”的概念,在锁定期间内,其他线程无法对被保护的数据进 行操作。在有些情况下两者可以互换。 两者之间的区别: 作用域 信号量: 进程间或线程间(linux仅线程间的无名信号量pthread semaphore) 互斥锁: 线程间 上锁时 信号量: 只要信号量的value大于0,其他线程就可以sem_wait成功,成功后信号量的value减一。若value值不大于0,则sem_wait使得线程阻塞,直到sem_post释放后value值加一,但是sem_wait返回之前还是会将此value值减一 互斥锁: 只要被锁住,其他任何线程都不可以访问被保护的资源 以下是信号灯(量

信号量 - semaphore

房东的猫 提交于 2020-03-22 17:12:27
一. POSIX - 信号量 #include <semaphore.h> sem_t sem; ///< 信号量 信号量,分为有名信号量 和无名信号量。 有名信号量由sem_open/sem_close/sem_unlink创建/关闭/销毁,用于进程间通信。 无名信号量由sem_init/sem_destroy创建/销毁,用于线程间通信。 1. 信号量初始化 /*********************************************************** * @param[sem] 非命名信号量,只能被sem_destroy()销毁, * @param[pshared] 非0表示进程间通信信号量,但是Linux系统暂未实现这一功能(实现方式为共享内存),0表示线程间通信信号量。 * @param[value] 信号量初始化值 * @return 成功返回0,失败返回-1及设置错误码errno *//********************************************************/ int sem_init(sem_t * sem, int pshared, unsigned vlaue); /*********************************************************** *

封装一个信号量集操作函数的工具

青春壹個敷衍的年華 提交于 2020-03-08 07:06:00
信号量的概念参见 这里 。 与消息队列和共享内存一样,信号量集也有自己的数据结构: struct semid_ds { struct ipc_perm sem_perm; /* Ownership and permissions */ time_t sem_otime; /* Last semop time */ time_t sem_ctime; /* Last change time */ unsigned short sem_nsems; /* No. of semaphores in set */ }; 同样地,第一个条目也是共有的ipc 对象内核结构,剩下的是私有成员。 Each semaphore in a semaphore set has the following associated values: unsigned short semval; /* semaphore value */ unsigned short semzcnt; /* # waiting for zero */ unsigned short semncnt; /* # waiting for increase */ pid_t sempid; /* process that did last op */ 即每一个在信号量集中的信号量都有上述4个相关的变量。 1、semval

Linux系统编程之信号量

你说的曾经没有我的故事 提交于 2020-03-07 02:11:53
原理: 1、信号量的概念 信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。 编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量值大于0时,则可以访问,否则将阻塞。 PV原语是对信号量的操作,一次P操作使信号量sem减1,一次V操作使信号量sem加1。 信号量主要用于进程或线程间的同步和互斥这两种典型情况。 (1)若用于互斥,几个进程(或线程)往往只设置一个信号量。 (2)若用于同步操作,往往会设置多个信号量,并且安排不同的初始值,来实现它们之间的执行顺序。 信号量用于互斥 信号量用于同步 例题1 :信号量实现互斥功能,模拟打印机 # include <stdio.h> # include <pthread.h> # include <unistd.h> # include <semaphore.h> sem_t sem ; void printer ( char * str ) { sem_wait ( & sem ) ; while ( * str ) { putchar ( * str ) ; fflush ( stdout ) ; str ++ ; sleep ( 1 ) ; } sem_post ( & sem ) ; } void * thread_fun1 ( void * arg ) {

6种Linux进程间的通信方式

淺唱寂寞╮ 提交于 2020-02-29 11:32:34
进程的概念 进程是操作系统的概念,每当我们执行一个程序时,对于操作系统来讲就创建了一个进程,在这个过程中,伴随着资源的分配和释放。可以认为进程是一个程序的一次执行过程。 进程通信的概念 进程用户空间是相互独立的,一般而言是不能相互访问的。但很多情况下进程间需要互相通信,来完成系统的某项功能。进程通过与内核及其它进程之间的互相通信来协调它们的行为。 进程通信的应用场景 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间。 共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。 资源共享:多个进程之间共享同样的资源。为了作到这一点,需要内核提供锁和同步机制。 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。 进程通信的方式 1.管道 管道分为有名管道和无名管道 无名管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用.进程的亲缘关系一般指的是父子关系。无明管道一般用于两个不同进程之间的通信。当一个进程创建了一个管道,并调用fork创建自己的一个子进程后,父进程关闭读管道端

【整理】pinlock与mutex

那年仲夏 提交于 2020-02-24 16:50:30
内核同步措施:为了避免并发防止竞争,内核提供了一组同步方法来提供对共享数据的保护。 Linux同步机制从2.0到2.6以来不断发展完善。从最初的原子操作,到后来的信号量,从大内核锁到自旋锁。这些同步机制的发展伴随 Linux 从单处理器到对称多处理器 的过度,伴随着从非抢占内核到抢占内核的过度。锁机制越来越有效,也越来越复杂。 目前,内核中原子操作多用来做计数使用,其它情况最常用的是两种锁及它们的变种: 一个是自旋锁,另一个是信号量。 自旋锁 :专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,不需要自旋锁)。 自旋锁最多只能被一个内核任务持有 ,如果一个内核任务试图请求一个已被争用(已经被持有)的自旋锁,那么这个任务就会一直进行忙循环——旋转——等待锁重新可用。要是锁未被争用,请求它的内核任务便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的内核任务同时进入临界区,因此这种锁可有效地避免多处理器上并发运行的内核任务竞争共享资源。 事实上,自旋锁的初衷就是:在短期间内进行轻量级的锁定。一个被争用的自旋锁使得请求它的线程在等待锁重新可用的期间进行自旋(特别浪费处理器时间),所以 自旋锁不应该被持有时间过长 。如果需要长时间锁定的话, 最好使用信号量。 自旋锁的基本形式如下: spin

信号量与自旋锁

懵懂的女人 提交于 2020-02-24 16:47:56
内核同步措施 为了避免并发,防止竞争。内核提供了一组同步方法来提供对共享数据的保护。 我们的重点不是介绍这些方法的详细用法,而是强调为什么使用这些方法和它们之间的差别。 Linux 使用的同步机制可以说从2.0到2.6以来不断发展完善。从最初的原子操作,到后来的信号量,从大内核锁到今天的自旋锁。这些同步机制的发展伴随 Linux从单处理器到对称多处理器的过度;伴随着从非抢占内核到抢占内核的过度。锁机制越来越有效,也越来越复杂。 目前来说内核中原子操作多用来做计数使用,其它情况最常用的是两种锁以及它们的变种:一个是自旋锁,另一个是信号量。我们下面就来着重介绍一下这两种锁机制。 自旋锁 ------------------------------------------------------ 自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,不需要自旋锁)。 自旋锁最多只能被一个内核任务持有,如果一个内核任务试图请求一个已被争用(已经被持有)的自旋锁,那么这个任务就会一直进行忙循环——旋转——等待锁重新可用。要是锁未被争用,请求它的内核任务便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的内核任务同时进入临界区,因此这种锁可有效地避免多处理器上并发运行的内核任务竞争共享资源。

linux自旋锁、互斥锁、信号量

|▌冷眼眸甩不掉的悲伤 提交于 2020-02-24 16:47:00
为了避免并发,防止竞争。内核提供了一组同步方法来提供对共享数据的保护。 我们的重点不是介绍这些方法的详细用法,而是强调为什么使用这些方法和它们之间的差别。 Linux 使用的同步机制可以说从2.0到2.6以来不断发展完善。从最初的原子操作,到后来的信号量,从大内核锁到今天的自旋锁。这些同步机制的发展伴随 Linux从单处理器到对称多处理器的过度;伴随着从非抢占内核到抢占内核的过度。锁机制越来越有效,也越来越复杂。 目前来说内核中原子操作多用来做计数使用,其它情况最常用的是两种锁以及它们的变种:一个是自旋锁,另一个是信号量。我们下面就来着重介绍一下这两种锁机制。 自旋锁 ------------------------------------------------------ 自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,不需要自旋锁)。 自旋锁最多只能被一个内核任务持有,如果一个内核任务试图请求一个已被争用(已经被持有)的自旋锁,那么这个任务就会一直进行忙循环——旋转——等待锁重新可用。要是锁未被争用,请求它的内核任务便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的内核任务同时进入临界区,因此这种锁可有效地避免多处理器上并发运行的内核任务竞争共享资源。 事实上

多线程编程总结

这一生的挚爱 提交于 2020-02-24 05:48:57
一、线程模型: 线程是程序中完成一个独立任务的完整执行序列,即一个可调度的实体。根据运行环境和调度者的身份,线程可分为 内核线程和 用户线程。 内核线程:运行在内核空间,由内核来调度; 用户线程:运行在用户空间,由线程库来调用。 当进程的一个内核线程获得CPU的使用权时,它就加载并运行一个用户线程。可见,内核程序相当于用户线程运行的容器。一个进程可以拥有M个内核线程和N个用户线程,其中M≤N。并且在一个系统的所有进程中,M和N的比值都是固定的。按照M:N的取值,线程的实现方式可分为三种模式: 完全在用户空间实现、 完全由内核调度和 双层调度。 1、完全在用户空间实现的线程无须内核的支持,内核甚至根本不知道这些现成的存在。线程库负责管理所有执行线程,比如线程的优先级、时间片等。线程库利用longjmp来切换线程的执行,使它们看起来像是“并发”执行的。但实际上内核仍然是把整个进程作为最小单位来调度的。换句话说,一个进程的所有执行线程共享该进程的时间片,它们对外表现出相同的优先级。因此,对于这种实现方式而言,M=1,即N个用户空间线程对应1个内核线程,而该内核线程实际上就是进程本身。 完全在用户空间实现的线程的优点是:创建和调度线程都无需内核的干预,因此速度相当快。并且由于它不占用额外的内核资源,所以即使一个进程创建了很多线程,也不会对系统性能造成明显的影响。其缺点是:对于多处理器系统

Linux基础知识3

吃可爱长大的小学妹 提交于 2020-02-17 14:22:51
原文链接:https://blog.csdn.net/zhouzhaoxiong1227/article/details/6876344 原文链接:https://blog.csdn.net/zhouzhaoxiong1227/article/details/6878477 原文链接:https://blog.csdn.net/zhouzhaoxiong1227/article/details/6882246 Q1. 什么是临界区?什么是竞争状态?什么是同步? A: 临界区(critical regions)就是访问和操作共享数据的代码段,多个内核任务并发访问同一个资源通常是不安全的; 如果两个内核任务可能处于同一个临界区,就是一种错误现象;如果确实发生了这种情况,就称它为竞争状态; 避免并发和防止竞争状态称为同步(synchronization)。 Q2. 简要介绍一下死锁及避免死锁的方法。 A: 死锁包括自死锁和ABBA死锁, 产生死锁有四个原因:互斥使用、不可抢占、请求和保持,以及循环等待; 避免死锁的方法有:破坏“不可剥夺”条件、破坏“请求和保持”条件、破坏“循环等待”条件。 Q3. 内核中造成并发执行的原因是什么? A: “并发”分为“伪并发”和“真并发”两种,内核中造成并发执行的原因有以下几种: 中断:它可能随时打断当前正在执行的代码; 内核抢占