进程通信之无名信号量

简介:

进程通信之无名信号量


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


依赖头文件:#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);

}


编译和运行结果:

[xqch@localhost testcases]$ gcc -o sem_nameless sem_nameless.c -lpthread

[xqch@localhost 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....



















本文转自存储之厨51CTO博客,原文链接:http://blog.51cto.com/xiamachao/1791534 ,如需转载请自行联系原作者


相关文章
|
10月前
|
消息中间件 Linux C++
c++ linux通过实现独立进程之间的通信和传递字符串 demo
的进程间通信机制,适用于父子进程之间的数据传输。希望本文能帮助您更好地理解和应用Linux管道,提升开发效率。 在实际开发中,除了管道,还可以根据具体需求选择消息队列、共享内存、套接字等其他进程间通信方
297 16
|
消息中间件 存储 供应链
进程间通信方式-----消息队列通信
【10月更文挑战第29天】消息队列通信是一种强大而灵活的进程间通信机制,它通过异步通信、解耦和缓冲等特性,为分布式系统和多进程应用提供了高效的通信方式。在实际应用中,需要根据具体的需求和场景,合理地选择和使用消息队列,以充分发挥其优势,同时注意其可能带来的复杂性和性能开销等问题。
|
存储 Unix Linux
进程间通信方式-----管道通信
【10月更文挑战第29天】管道通信是一种重要的进程间通信机制,它为进程间的数据传输和同步提供了一种简单有效的方法。通过合理地使用管道通信,可以实现不同进程之间的协作,提高系统的整体性能和效率。
|
11月前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
843 20
|
Java Android开发 数据安全/隐私保护
Android中多进程通信有几种方式?需要注意哪些问题?
本文介绍了Android中的多进程通信(IPC),探讨了IPC的重要性及其实现方式,如Intent、Binder、AIDL等,并通过一个使用Binder机制的示例详细说明了其实现过程。
949 4
|
Linux C语言
C语言 多进程编程(七)信号量
本文档详细介绍了进程间通信中的信号量机制。首先解释了资源竞争、临界资源和临界区的概念,并重点阐述了信号量如何解决这些问题。信号量作为一种协调共享资源访问的机制,包括互斥和同步两方面。文档还详细描述了无名信号量的初始化、等待、释放及销毁等操作,并提供了相应的 C 语言示例代码。此外,还介绍了如何创建信号量集合、初始化信号量以及信号量的操作方法。最后,通过实际示例展示了信号量在进程互斥和同步中的应用,包括如何使用信号量避免资源竞争,并实现了父子进程间的同步输出。附带的 `sem.h` 和 `sem.c` 文件提供了信号量操作的具体实现。
|
消息中间件 Linux 开发者
Linux进程间通信秘籍:管道、消息队列、信号量,一文让你彻底解锁!
【8月更文挑战第25天】本文概述了Linux系统中常用的五种进程间通信(IPC)模式:管道、消息队列、信号量、共享内存与套接字。通过示例代码展示了每种模式的应用场景。了解这些IPC机制及其特点有助于开发者根据具体需求选择合适的通信方式,促进多进程间的高效协作。
601 3
|
存储 Python
Python中的多进程通信实践指南
Python中的多进程通信实践指南
219 0
Linux源码阅读笔记13-进程通信组件中
Linux源码阅读笔记13-进程通信组件中
|
消息中间件 安全 Java
Linux源码阅读笔记13-进程通信组件上
Linux源码阅读笔记13-进程通信组件上

热门文章

最新文章