sem

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

感情迁移 提交于 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); /*********************************************************** *

操作系统7-信号量与管程

旧街凉风 提交于 2020-03-17 15:31:59
回顾一下 : 并发问题:多线程并发导致资源竞争 同步概念: ---------1. 协调多线程对 共享数据 的访问 ---------2.任何时刻只能由一个线程执行临界区代码 确保同步正确的方法 ---------底层硬件支持 ---------高层次的编程抽象( 锁 ) 信号量是锁机制在同一层上的高层抽象编程方法 一、 信号量semaphore 信号量是操作系统提供的一种 协调共享资源访问 的方法, 用信号量表示系统资源的数量 信号是一种抽象数据类型,由一个整型(sem)变量和两个原子操作组成: 1)P():sem减1,如sem<0,表示申请资源(减1)后没有资源了,需要等待 2)V():sem加1,如sem<=0,即一个资源用完(加1)但还是小于0表示还有资源在等待,那么就唤醒一个等待进程 信号量是被保护的整数变量。初始化完成后就只能通过P()和V()操作来修改,并且由操作系统来保证PV操作时原子操作 P可能由于没有资源而进入阻塞状态,但是V操作不会被阻塞 假定信号量实现的同步是公平的,线程不会被阻塞在P()操作中,并且信号量等待按先进先出 信号量的实现 class Semophore { int sem ; WaitQueue q ; } Semophore :: P ( ) { sem -- ; //申请一个资源 if ( sem < 0 ) //资源不够,要等待 {

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

青春壹個敷衍的年華 提交于 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

多线程编程总结

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

C#多线程那点事——信号量(Semaphore)

≯℡__Kan透↙ 提交于 2020-02-18 10:27:40
信号量说简单点就是为了线程同步,或者说是为了限制线程能运行的数量。 那它又是怎么限制线程的数量的哩?是因为它内部有个计数器,比如你想限制最多5个线程运行,那么这个计数器的值就会被设置成5,如果一个线程调用了这个Semaphore,那么它的计数器就会相应的减1,直到这个计数器变为0。这时,如果有另一个线程继续调用这个Semaphore,那么这个线程就会被阻塞。 获得Semaphore的线程处理完它的逻辑之后,你就可以调用它的Release()函数将它的计数器重新加1,这样其它被阻塞的线程就可以得到调用了。 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading;namespace Semaphore1{ class Program { //我设置一个最大允许5个线程允许的信号量 //并将它的计数器的初始值设为0 //这就是说除了调用该信号量的线程都将被阻塞 static Semaphore semaphore = new Semaphore(0, 5); static void Main(string[] args) { for (int i = 1; i <= 5; i++) { Thread thread = new

Posix信号量

血红的双手。 提交于 2020-02-13 00:02:42
1、概述   信号量(semaphore)是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语。信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有。信号量的值为正的时候,说明它空闲。所测试的线程可以锁定而使用它。若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒。Posix信号量分为有名信号量和无名信号量(也叫基于内存的信号量)。 2、Posix有名信号量   有名信号量既可以用于线程间的同步也可以用于进程间的同步。 1)由sem_open来创建一个新的信号量或打开一个已存在的信号量。其格式为: sem_t *sem_open(const char *name,int oflag,mode_t mode,unsigned int value); 返回:若成功则为指向信号量的指针,若出错则为SEM_FAILED 其中,第三、四个参数可以没有,主要看第二个参数如何选取。 oflag参数:可以是0、O_CREAT或O_CREAT|O_EXCL。如果指定O_CREAT标志而没有指定O_EXCL,那么只有当所需的信号量尚未存在时才初始化它。但是如果所需的信号量已经存在也不会出错。 但是如果在所需的信号量存在的情况下指定O_CREAT|O_EXCL却会报错。 mode参数:指定权限位。 value参数:指定信号量的初始值

IPC通信:Posix信号灯

假装没事ソ 提交于 2020-02-12 23:23:46
  信号灯用来实现 同步 ——用于多线程,多进程之间同步共享资源(临界资源)。信号灯分两种,一种是有名信号灯,一种是基于内存的信号灯。 有名信号灯 ,是根据外部名字标识,通常指代文件系统中的某个文件。 而基于内存的信号灯 ,它主要是把信号灯放入内存的,基于内存的信号灯,同步多线程时,可以放到该多线程所属进程空间里;如果是同步多进程,那就需要把信号灯放入到共享内存中(方便多个进程访问)。   有名信号灯和基于内存的信号灯,具体区别体现在创建和销毁两个函数。有名信号灯使用sem_open和sem_close函数。基于内存的信号灯使用sem_init和sem_destroy函数。sem_init的参数可以控制是同步多线程,还是多进程;且该函数只能调用1次,因为调用后信号灯就存在了( 内存指针存在)。一般,使用基于内存的信号灯同步同进程多线程,使用有名信号灯同步多进程。 有名信号灯同步多线程: 1 1.sem_open函数。 2 功能:创建并初始化信号灯,如果存在就返回存在的信号灯。 3 头文件:#include <semaphore.h> 4 函数原型:sem_t * sem_open(const char * name,int oflag,mode_t mode,unsigned int value); 5 或者:sem_t * sem_open(const char * name

system V信号量和Posix信号量

五迷三道 提交于 2020-02-12 23:20:43
一、函数上的区别 信号量有两种实现:传统的System V信号量和新的POSIX信号量。它们所提供的函数很容易被区分:对于所有System V信号量函数,在它们的名字里面没有下划线。例如,应该是semget()而不是sem_get()。然而,所有的的POSIX信号量函数都有一个下划线。下面列出了它们提供的所有函数清单: Systm V POSIX semctl() sem_getvalue() semget() sem_post() semop() sem_timedwait() sem_trywait() sem_wait() sem_destroy() sem_init() sem_close() sem_open() sem_unlink() 二、使用上的区别 1、XSI system V的信号量是信号量集,可以包括多个信号灯(有个数组),每个操作可以同时操作多个信号灯 posix是单个信号灯,POSIX有名信号灯支持进程间通信,无名信号灯放在共享内存中时可以用于进程间通信。 2、POSIX信号量在有些平台并没有被实现,比如:SUSE8,而SYSTEM V大多数LINUX/UNIX都已经实现。两者都可以用于进程和线程间通信。但一般来说,system v信号量用于 进程间同步、有名信号灯既可用于线程间的同步,又可以用于进程间的同步、posix无名用于同一个进程的不同线程间

linuxC多进程通讯----POSIX信号量

≡放荡痞女 提交于 2020-02-08 09:39:07
文章目录 相关API 使用说明 基本创建、加减、关闭示例 两个进程通过信号量通讯示例 post wait 父子进程通过信号量同步 相关API •sem_t *sem_open (const char *name, int oflag); •sem_t *sem_open (const char *name, int oflag,mode_t mode, unsigned int value); •int sem_close (sem_t *sem); •int sem_post (sem_t *sem); •int sem_wait (sem_t *sem); •int sem_trywait (sem_t *sem); •int sem_timedwait (sem_t *sem, const struct timespec *abs_timeout); •int sem_unlink (const char *name); •int sem_getvalue (sem_t *sem, int *sval); 使用说明 •包含头文件:#include <semaphore.h> •编译时要指定:-lpthread •Pthread: –POSIX threads,操作线程的API标准 –适用于 Unix、Linux、Mac OS 基本创建、加减、关闭示例 #include