Linux IPC实践(11) --System V信号量(1)】的更多相关文章

信号量API #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> int semget(key_t key, int nsems, int semflg); int semctl(int semid, int semnum, int cmd, ...); int semop(int semid, struct sembuf *sops, unsigned nsops); semget int…
实践1:信号量实现进程互斥 父子进程执行流程如下: 父进程 子进程 P P O(print) X(print) sleep sleep O(print) X(print) V V sleep sleep 从图中可以看出, O或X总是成对出现的, 要么两个O, 要么两个X; /**P,V原语实现父子进程互斥使用终端**/ // 程序代码 int main(int argc,char *argv[]) { int semid = sem_create(IPC_PRIVATE); sem_setval…
共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg); void *shmat(int shmid, const void *shmaddr, int shmflg); int shmdt(const void *shmaddr); int shmctl(int shmid, int cmd, struct shmid_ds *buf); //…
消息队列综合案例 消息队列实现回射客户/服务器   server进程接收时, 指定msgtyp为0, 从队首不断接收消息 server进程发送时, 将mtype指定为接收到的client进程的pid client进程发送的时候, mtype指定为自己进程的pid client进程接收时, 需要将msgtyp指定为自己进程的pid, 只接收消息类型为自己pid的消息; // client/server进程接收/发送的数据结构 const int MSGMAX = 8192; struct msgB…
实践:实现一个先进先出的共享内存shmfifo 使用消息队列即可实现消息的先进先出(FIFO), 但是使用共享内存实现消息的先进先出则更加快速; 我们首先完成C语言版本的shmfifo(基于过程调用), 然后在此基础上实现C++版本的ShmFifo, 将1块共享内存与3个信号量(1个mutext信号量, 1个full信号量, 1个empty信号量)封装成一个类ShmFifo, 然后编写各自的测试代码; shmfifo说明: 将申请到的共享内存作为一块缓冲区, 将该内存的首部(p_shm到p_pa…
消息队列概述 消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法(仅局限于本机); 每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值. 消息队列也有管道一样的不足: (1)每个消息的最长字节数的上限(MSGMAX); (2)系统中消息队列的总条数也有一个上限(MSGMNI); (3)每个消息队列所能够保存的总字节数是有上限的(MSGMNB) . 查看系统限制 cat /proc/sys/kernel/msgmax  #最大消息长度限制 cat /proc/sys…
消息发送/接收API msgsnd函数 int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 参数 msgid: 由msgget函数返回的消息队列标识码, 也可以是通过ipcs命令查询出来的一个已经存在的消息队列的ID号 msgp:是一个指针,指针指向准备发送的消息, msgsz:是msgp指向的消息长度, 注意:这个长度不含保存消息类型的那个long int长整型 msgflg:控制着当前消息队列满或到达系统上限时…
今天起,学习信号量相关的知识,下面开始: 关于信号量,在前面已经介绍过了,这里回顾一下: 通过上面的描述,很容易就能想到信号量的一上数据结构: 下面再来回顾一下P.V原语: 所谓的原语就是指这段代码是原子性的,是不会被其它信号中断的, 在Linux中,system v 信号量是以信号量集来实现的,跟其它system v IPC对象一样,也有自己的数据结构: 同样的,信号量集也提供了一些函数来操作: 下面一一对其进行学习: 下面用具体代码来实践一下,会封装一些对信号量集的一些函数: 编译运行: 另…
今天迎来元旦假期的最后一天了,过得好快~昨天跟小伙伴们在军都滑雪陪儿爽,虽说上了两回中级道都摔得异常的惨烈,但是在初级道上学习"s"转弯还是有一些小心得,可以在要往高手迈进的前提,一定得要把基本功打扎实,否则会很惨烈~好了,在这无聊的下午,用博客继续充实自己. 上次学习了System v 信号量的一些概念,并封装了一些常用方法,下面会举例用信号量来实现进程互斥,来进一步加深对信号量的认识. 先用图来描述一下这个程序的一个意图: 下面则开始实现,基于之前信号量的封装: print.c:…
在进程同步,并发运行时,保证按序地访问共享资源是十分重要的.因此引入了临界区的概念,一次只能有一个线程进入临界区完成他的指令.而信号量(semaphore)的作用,类似于一个交通信号灯,它负责进程协作,因此信号量又称为信号灯. 在Linux系统中,它提供两种信号量: 内核信号量,由内核控制路径使用 用户态进程使用的信号量,这种信号量有两种接口,POSIX信号量和SYSTEM V信号量. 信号量的本质是一个计数器.一个较为常见的用法,是为每个资源都会分配一个信号量.记信号量为S,除了初始化之外,有…
11.1 概述 信号量按功能分:二值信号量.计数信号量.信号量集:其中二值信号量和计数信号量指的是Posix信号量,信号量集指的是System V信号量.…
前面已经介绍过了POSIX共享内存区,System V共享内存区在概念上类似POSIX共享内存区,POSIX共享内存区的使用是调用shm_open创建共享内存区后调用mmap进行内存区的映射,而System V共享内存区则是调用shmget创建共享内存区然后调用shmat进行内存区的映射. 对每个System V共享内存区,内核会维护一个shmid_ds的数据结构,Linux 2.6.18 中的定义如下: <bits/shm.h> /* 连接共享内存区的进程数的数据类型 */ typedef…
一.函数上的区别 信号量有两种实现:传统的System V信号量和新的POSIX信号量.它们所提供的函数很容易被区分:对于所有System V信号量函数,在它们的名字里面没有下划线.例如,应该是semget()而不是sem_get().然而,所有的的POSIX信号量函数都有一个下划线.下面列出了它们提供的所有函数清单: Systm V POSIX semctl() sem_getvalue() semget() sem_post() semop() sem_timedwait() sem_try…
System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的系统内核中,后来商用UNIX系统基本都加入了System V IPC的功能. System V消息队列相对于POSIX消息队列的区别主要是: POSIX消息队列的读操作总是返回消息队列中优先级最高的最早消息,而对于System V消息队列可以返回任意指定优先级(通过消息类型)的消息. 当向一个空消息…
信号量对比 二值信号量:其值要么0要么1,比如互斥锁就是这种类型 计数信号量:其值为0或某个正整数,比如POSIX 信号量 计数信号量:一个或多个信号量构成一个集合,每个都是计数信号量,比如System V信号量 shell查看命令:ipcs -s 基本函数 #include <sys/ipc.h> key_t ftok(char *fname,int id); #include <sys/sem.h> int semget(key_t key,int nsems,int ofla…
1. 信号量(semaphore)主要用于保护临界资源.进程可以根据它判断是否能访问某些共享资源.信号量除了用于访问控制外,还可用于进程同步,也就是进程间通信.2. 信号量分类:a. 二值信号量: 信号量的值只能取0或1,类似于互斥锁mutex,但两者又不同:mutex 与 二值信号量的区别:信号量强调共享资源,只要共享资源可用,其他进程同样可以修改信号量的值:互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来接锁.b. 计数信号量:信号量的值可以取任意非负值. system V信号…
System V 信号量 在提到Posix 信号量时,指的是二值信号量或计数信号量,而System V信号量指的是入了计数信号量集 二值信号量:其值为0或1,类似于互斥锁,资源被锁住时为0,资源可用为1计数信号量:其值在0和某个限制值之间的信号量,信号量的值就是可用资源数计数信号量集:一个或多个信号量构成一个集合,集合中每个元素都是计数信号量(每个集合的信号量数存在一个限制) semid_ds结构: 内核为每个信号量集维护的信息结构 #include <sys/sem.h> struct se…
模型 #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> ftok() //获取key semget() //创建/获取信号量集 semctl() //初始化信号量集 semop() //操作信号量集 semctl() //删除信号量集 ftok() //获取key值, key值是System V IPC的标识符,成功返回key,失败返回-1设errno //同pathname+同 proj_…
进程间通信的机制--信号量.注意请不要把它与之前所说的信号混淆起来,信号与信号量是不同的两种事物.有关信号的很多其它内容,能够阅读我的还有一篇文章:Linux进程间通信--使用信号.以下就进入信号量的解说. 一.什么是信号量 为了防止出现因多个程序同一时候訪问一个共享资源而引发的一系列问题,我们须要一种方法,它能够通过生成并使用令牌来授权,在任一时刻仅仅能有一个运行线程訪问代码的临界区域.临界区域是指运行数据更新的代码须要独占式地运行.而信号量就能够提供这种一种訪问机制,让一个临界区同一时间仅仅…
进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些资源一次只允许一个进程使用,称这样的资源为临界资源或互斥资源, 而在进程中涉及到互斥资源的程序段叫临界区. Linux IPC发展 Linux下的进程通信手段基本上是从UNIX平台上的进程通信手段继承而来的.而对UNIX发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克…
1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For mode constants */ #include <mqueue.h> mqd_t mq_open(const char *name, int oflag); //专用于打开一个消息队列 mqd_t mq_open(const char *name, int oflag, mode_t mode…
消息队列可以认为是一个消息链表,System V 消息队列使用消息队列标识符标识.具有足 够特权的任何进程都可以往一个队列放置一个消息,具有足够特权的任何进程都可以从一个给定队列读出一个消息.在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达.System V 消息队列是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除.可以将内核中的某个特定的消息队列画为一个消息链表,如下图所示: 对于系统中每个消息队列,内核维护一个msqid_ds的…
传统的Linux init有两种风格,System V风格和BSD风格,本文主要介绍System V风格. System V风格init的主要流程是, 1. 内核执行init进程. 2. Init 运行 /etc/rc.d/rc.sysinit. 3. Rc.sysinit 运行rc.serial 4. init运行所有默认运行级别下的启动脚本. 5. init运行rc.local. 其中涉及到的初始化脚本和目录有  Init.d目录包含真正的服务脚本,脚本的编写必须满足服务脚本的编写规则. r…
今天继续学习system v消息队列,主要是学习两个函数的使用,开始进入正题: 下面则开始用代码来使用一下该发送函数: 在运行之前,先查看一下1234消息队列是否已经创建: 用上次编写的查看消息队列状态的程序来查看一下此时的状态: 接下来运行发送消息程序: 接下来再来发送一个消息: 目前发送的字节总数为300,还没有超过最大字节数msgmnb=16384,下面来看下如果超过了这个字节数,会怎么样?所以继续发送消息: 这是由于每条消息最大长度是有上限的(MSGMAX),它的上线就等于8192: 这…
接着上次的共享内存继续学习,这次主要是学习system v共享内存的使用,下面继续: 跟消息队列一样,共享内存也是有自己的数据结构的,system v共享内存也是随内核持续的,也就是说当最后一个访问内存共享的进程结束了,内核也不会自动删除共享内存段,除非显示去删除共享内在,其数据结构跟消息队列很类似: 跟消息队列一样,共享内存也提供了四个函数: 下面详细来看一下各函数的用法: 用法跟msgget函数一模一样,下面用代码来实验一下: 编译运行一下: 当共享内存创建好之后,则希望往共享内存当中进行写…
信号量 IPC 原理 信号量通信机制主要用来实现进程间同步,避免并发访问共享资源.信号量可以标识系统可用资源的个数.最简单的信号量为二元信号量 下图为 Linux 信号量通信机制的概念图.在实际应用中,两个进程通信可能会使用多个信号量,因此,Linux 在管理时以信号量集合的概念来管理. 通常所说的创建一个信号量实际上是创建了一个信号量集合,在这个信号量集合中,可能有多个信号量.整个信号量集合由以下部分组成. 1.信号量集合数据结构:在此数据结构中定义了整个信号量集合的基本属性,如访问权限. 2…
信号量 信号量和P.V原语由Dijkstra(迪杰斯特拉)提出 信号量: 互斥: P.V在同一进程中 同步: P.V在不同进程中 信号量值含义 S>0 : S表示可用资源个数 S=0 : 表示无可用资源,无等待进程 S<0 : |S|表示等待队列中进程个数 信号量集结构 struct semid_ds { struct ipc_perm sem_perm; /* Ownership and permissions */ time_t sem_otime; /* Last semop time…
1 概述 计数信号量集semid_ds: struct semid_ds { struct ipc_perm sem_perm; struct sem *sem_base; //指向信号量结构数组 unsigned short sem_nsems; //信号量集中信号量数目 time_t sem_otime; //last semop时间 time_t sem_ctime; }; sem结构是内核用于维护某个给定信号量的内部数据结构: struct sem { unsigned short se…
概述 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图). 共享内存 VS. 其他IPC形式 用管道/消息队列传递数据 用共享内存传递数据 共享内存生成之后,传递数据并不需要再走Linux内核,共享内存允许两个或多个进程共享一个给定的存储区域,数据并不需要在多个进程之间进行复制,因此,共享内存的传输速度更快! mmap内存映射 将文件/设备空间映射到共享内存区 #incl…
n哲学家进餐问题描述有五个哲学家,他们的生活方式是交替地进行思考和进餐,n哲学家们共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,n平时哲学家进行思考,饥饿时便试图取其左.右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,n进餐完毕,放下筷子又继续思考. 约束条件 (1)只有拿到两只筷子时,哲学家才能吃饭. (2)如果筷子已被别人拿走,则必须等别人吃完之后才能拿到筷子. (3)任一哲学家在自己未拿到两只筷子吃饭前,不会放下手中拿到的筷子. 问题的产生 如果5个哲学家同时拿起了…