进程通信之无名信号量

和有名信号量类似,无名信号也是进程之间/线程之间通信的主要手段,唯一不同的是他不能用在不同进程之间。当然如果把无名信号量放在多个进程都可以访问的共享内存里,也可以实现进程之间的通信,但这主要还是借助于共享内存的机制。下面将根据使用无名信号量依赖的头文件、需要链接的库文件、常用的函数分别进行介绍。

依赖头文件:#include
<semaphore.h>

链接依赖库:
需要链接到libpthread.so,因此makefile里需要指定-lpthread

重要函数列表:

int
sem_init(sem_t *sem, int pshared, unsigned int value);

无名信号量的初始化函数,这个函数体现了无名信号量和有名信号量的主要区别,不同于有名信号量的初始化函数sem_open(),它不需要指定一个文件名,只需要传递一个进程、线程都可以访问的信号量指针进去就可以。如果需要在同一个进程的不同线程之间访问,那么pshared必须设置为0,并且第一参数必须保证每个线程都可以访问;如果需要在不同进程间访问,那么pshared必须设置为1,并且第一个参数必须放在共享内存区域。这个函数的地三个参数value指定了该信号量初始化的值,它代表系统刚开始可用的系统资源的个数。

当上面的函数返回为0时,表示函数调用成功;当返回为-1的时候,代表出错,错误代码放在errno里面,可以通过strerror(errno)打印出来。

int
sem_post(sem_t *sem);

unlock无名信号量,并且把可用的资源个数加1,唤醒等待当前信号量的线程或进程,让被唤醒的进程或线程可以拿到锁。函数返回值同上。

int
sem_wait(sem_t *sem);

int
sem_trywait(sem_t *sem);

int
sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

上面的三个函数都能查询当前有没有可用资源,如果有:就抢到锁并把当前可用的资源数目减1。如果没有可用资源:不同的是sem_wait()会把当前进程或线程加入到休眠队列,直到被唤醒;而sem_trywait()函数在系统没有可用资源的情况下会立即返回错误,并把错误代码设置为EAGAIN,当前进程或线程不会被阻塞;而sem_timewait()在没有可用资源的情况下,最长会被阻塞abs_timeout的时长,然后返回错误,并把错误代码设置为ETIMEDOUT。

int
sem_getvalue(sem_t *sem, int *sval);

得到当前信号量的值(代表当前系统可用资源的数量),并把它放到sval指向的内存里面。

代码示例

#include
<stdio.h>

#include
<stdint.h>

#include
<stdlib.h>

#include
<string.h>

#include
<assert.h>

#include
<sys/types.h>

#include
<sys/ipc.h>

#include
<sys/sem.h>

#include
<fcntl.h>           /* For O_* constants */

#include
<sys/stat.h>        /* For mode constants */

#include
<semaphore.h>

#include
<errno.h>

sem_t
clnt_sem;

int
create_done = 0;

void
state_thread1()

{

while(1) {

if
(!create_done) continue;

printf("%s:
Wait semp....\n", __FUNCTION__);

sem_wait(&clnt_sem);

printf("%s:
Wait semp done: semp comes\n",  __FUNCTION__);

}

}

void
state_thread2()

{

while(1) {

printf("%s:
Wait semp....\n", __FUNCTION__);

sem_wait(&clnt_sem);

printf("%s:
Wait semp done: semp comes\n",  __FUNCTION__);

sleep(10);

}

}

void
main(void)

{

pthread_t
ftids;

int
ret;

ret
= sem_init(&clnt_sem,0, 3);

if
(ret < 0) {

printf("%s\n",
strerror(errno));

}

pthread_create(&ftids,
NULL, (void *)state_thread1, NULL);

pthread_create(&ftids,
NULL, (void *)state_thread2, NULL);

create_done =
1;

sem_post(&clnt_sem);

while(1) {

printf("IN
Clnt main process\n");

sleep(10);

}

编译和运行结果:

[[email protected]
testcases]$ gcc -o sem_nameless sem_nameless.c -lpthread

[[email protected]
testcases]$ ./sem_nameless

IN
Clnt main process

state_thread2:
Wait semp....

state_thread2:
Wait semp done: semp comes

state_thread1:
Wait semp....

state_thread1:
Wait semp done: semp comes

state_thread1:
Wait semp....

state_thread1:
Wait semp done: semp comes

state_thread1:
Wait semp....

state_thread1:
Wait semp done: semp comes

state_thread1:
Wait semp....

IN
Clnt main process

state_thread2:
Wait semp....

时间: 2024-12-28 22:07:05

进程通信之无名信号量的相关文章

进程通信概念简介 多线程上篇(六)

进程通信指的是进程间的信息交换 ,IPC(Inter-Process Communication,进程间通信) 之前说到: 进程通信就相当于一种工作方式.沟通形式,比如你给我一个SVN标签号并且告知我意图,我去库中检索指定标签修改的指定内容,就完成了一个任务的协作. 进程同步中,也有信息的交换,比如互斥量访问,再比如生产者和消费者,共享缓冲池,但是这些通常被称之为低级的进程通信. 以信号量为例,如果你说我在塔顶点亮灯表示危险,否则表示安全,这没问题,如果你想用灯亮灯灭来像QQ一样,大段大段的传递

Linux 进程通信之 ——信号和信号量总结

如今最经常使用的进程间通信的方式有:信号,信号量,消息队列,共享内存.       所谓进程通信,就是不同进程之间进行一些"接触",这种接触有简单,也有复杂.机制不同,复杂度也不一样.通信是一个广义上的意义,不仅仅指传递一些massege.他们的用法是基本相同的,所以仅仅要掌握了一种的用法,然后记住其他的用法就能够了. 1. 信号       在我学习的内容中,主要接触了信号来实现同步的机制,据说信号也能够用来做其他的事      情,可是我还不知道做什么.       信号和信号量是

linux进程通信之SYSTEM V信号量

信号量的使用主要是用来保护共享资源,使得资源在一个时刻只有一个进程(线程)所拥有.信号量的值为正的时候,说明它空闲.所测试的线程可以锁定而使用它.若为0,说明它被占用,测试的线程要进入睡眠队列中,等待被唤醒. 一.信号量的分类: 在学习信号量之前,我们必须先知道--Linux提供两种信号量: (1) 内核信号量,由内核控制路径使用. (2) 用户态进程使用的信号量,这种信号量又分为POSIX信号量和SYSTEM V信号量. POSIX信号量又分为有名信号量和无名信号量.有名信号量,其值保存在文件

进程通信(二)&mdash;&mdash; 信号量&amp;内存共享

内存共享是进程间常用的通信方式,可以实现两个完全独立的进程通信. 在访问共享内存时,同时需要信号量进行访问控制. 使用ipcs -m命令可以查看系统共享内存,ipce -m + key 可以删除指定的共享内存. 对共享内存操作时,使用信号量对共享内存进行保护,类似与线程中的互斥锁.都可以看做是通过PV操作实现临界资源保护. P:对信号量标记位-1,获取信号量,如果标记位为0,表示有其他进程占用资源,无法获取. V:对信号量标记位+1,释放信号量,将资源释放,给其他进程使用. 信号量和内存共享需要

进程通信(信号量)

信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的 通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识.信号 量在此过程中负责数据操作的互斥.同步等功能. 当请求一个使用信号量来表示的资源时,进程需要先读取信号量的值来判断资源是否可用.大于0,资源可以请求,等于0,无资源可用,进程会进入睡眠状态直至资源可用. 当进程不再使用一个信号量控制的共享资源时,信号量的值+1,对信号量的值进行的增减 操作均为原子操作,这是由于信号量主要的作用是维护资源的互斥

进程通信-无名管道

无名管道:主要是针对进程通信的(自己感觉它有很大的局限性) 特点:它不是一个文件系统,不能按名访问,这也是它和有名管道之间最大的区别.无名管道只是一个系统内存里面的东西. 半双工模式,数据只能流向一个方向(老师给我们举得例子就是水厂的水到居民用水,不可能倒着流对吧). 进程之间通信,但是只能是有亲缘关系的进程才能进行通信?比如父子进程:因为在父子进程中,子进程拷贝父进程的数据段,这让这两个进程在通信的时候就有了相连的关系. 下面我们来看一下:无名管道的创建,写入,读取,关闭(我用的的是Liunx

第七课 进程通信

unix_c_07.txt================第七课 进程通信================一.基本概念------------1. 何为进程间通信~~~~~~~~~~~~~~~~~进程间通信(Interprocess Communication, IPC)是指两个,或多个进程之间进行数据交换的过程.2. 进程间通信分类~~~~~~~~~~~~~~~~~1) 简单进程间通信:命令行参数.环境变量.信号.文件.2) 传统进程间通信:管道(fifo/pipe).3) XSI进程间通信:

Linux系统编程@进程通信(一)

进程间通信概述 需要进程通信的原因: 数据传输 资源共享 通知事件 进程控制 Linux进程间通信(IPC)发展由来 Unix进程间通信 基于System V进程间通信(System V:UNIX系统的一个分支) POSIX进程间通信(POSIX:可移植操作系统接口,为了提高UNIX环境下应用程序的可移植性.很多其他系统也支持POSIX标准(如:DEC OpenVMS和Windows).) 现在Linux使用的进程间通信方式包括: 管道(pipe).有名管道(FIFO) 信号(signal) 消

Linux进程通信——管道

进程间通信(IPC:Inner Proceeding Communication) 进程是操作系统实现程序独占系统运行的假象的方法,是对处理器.主存.I/O设备的抽象表示.每个进程都是一个独立的资源管理单元,每个进程所看到的是自己独占使用系统的假象,因此各个进程之间是不能够直接的访问对方进程的资源的,不同的进程之间进行信息交互需要借助操作系统提供的特殊的进程通信机制. 进程之间的通信,从物理上分,可以分为同主机的进程之间的通信和不同主机间的进程之间的通信.从通信内容方式上分,可以分为数据交互.同