进线程通信之有名信号量

简介:

 有名信号量 semphore


如果说信号是外部事件和进程的关联的机制的话,那么信号量就是进程、线程之间通信的机制。根据是支持不同进程之间的通信还是同一个进程内不同线程的通信,信号量可以分为有名信号量和无名信号量。顾名思义,有名信号量在建立起来时需要显式地指名一个信号量的名字,在linux这个名字对应到/dev/shm-semphorename这个共享内存的映射文件,由于它可以被不同进程同时访问,因而可以在不同进程之间实现通信;而无名信号仅仅用在同一个进程内部的不同线程之间,由于不同线程共享创建它们的进程的资源,因而无需显示地指定任何可以共同访问的名称或文件。两者的共同点是都支持经典的P/V操作,在申请信号量的时候,如果申请不到可以被调度到休眠状态,直至被V操作唤醒。


下面基于CentOS Linux系统分别进行介绍有名信号量和无名信号量。


有名信号量


依赖头文件

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

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

#include <semaphore.h>


常用函数


创建有名信号量

sem_t *sem_open(const char *name, int oflag);

sem_t *sem_open(const char *name, int oflag,  mode_t mode, unsigned int value);


P操作

int sem_wait(sem_t *sem); //如果信号量不大于0,则当前线程或进程一直阻塞到信号量大于0


int sem_trywait(sem_t *sem);//如果信号量不大于0,返回出错值并不会阻塞当前线程或进程


int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);//如果信号量不大于0,当前线程或进程会被阻塞abs_timeout指定的时间,然后继续进入运行队列



V操作

int sem_post(sem_t *sem);


关闭信号

int sem_close(sem_t *sem); //使得系统允许任何为这个信号量申请的任何资源可以被释放

int sem_unlink(sem_t *sem);//删除sem指向的有名信号量


查询当前信号量的值

int sem_getvalue(sem_t *sem, int *sval);//把当前信号量的值读取到sval当中去。



连接依赖库

依赖于线程库,在链接的时候需要加上-lpthread。


代码实例:sem_svc.c

#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>


const char * fname = "tstmy";

void main(void)

{

pthread_t ftids;


sem_t * svc_sem;


svc_sem = sem_open(fname, O_CREAT | O_EXCL, 0644, 0);


printf("Will post semp soon ...\n");

sleep(2);

sem_post(svc_sem);


printf("Will post semp again ...\n");

sleep(2);

sem_post(svc_sem);


printf("Post semp done!\n");


sem_close(svc_sem);

sem_unlink(fname);

}


sem_clnt.c:

#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>

const char * fname = "tstmy";


sem_t * clnt_sem;


void state_thread()

{

while(1) {

printf("Wait semp....\n");

sem_wait(clnt_sem);

printf("Wait semp done: semp comes\n");

}

}  


void main(void)

{

pthread_t ftids;


clnt_sem = sem_open(fname,O_EXCL);


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


while(1) {

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

sleep(1);

}

}


编译链接如下:

[xmch@localhost testcases]$ gcc -o sem_svc sem_svc.c -lpthread

[xmch@localhost testcases]$ gcc -o sem_clnt sem_clnt.c -lpthread



典型应用场景:

1.基于它实现多个进程之间的读写锁/或者生产者消费者模型;

2.需要实现属于不同进程的多个线程之间的通信同步关系;


注意:上面实例代码sem_svc.c中的sem_close()和sem_unlink不能忽略掉,否则下次运行执行到sem_open()时候会出错,务必引起重视,特别地在多线程、进程的环境下,这两个函数建议放在系统或者模块的清理函数(de-init或者destruct)中去执行。





















本文转自存储之厨51CTO博客,原文链接:http://blog.51cto.com/xiamachao/1784665 ,如需转载请自行联系原作者
相关文章
|
1月前
|
存储 Java 数据库连接
java多线程之线程通信
java多线程之线程通信
|
2月前
|
Python
如何在Python中实现线程之间的同步和通信?
【2月更文挑战第17天】【2月更文挑战第51篇】如何在Python中实现线程之间的同步和通信?
|
5月前
|
Java
线程间通信之Object.wait/notify实现
线程间通信之Object.wait/notify实现
30 0
|
5月前
|
消息中间件 存储 Unix
进程间通信和线程间通信总结
写在前面 面试的时候一定不要疲劳战,比如上午面了一个,然后中午不休息直接赶到另外一个相距比较远的公司,影响状态。 面试的时候一定不要紧张,不管对方有几个人,总之面试的时候做好充分准备,休息好,放松心态。 好了,言归正传,开始总结。
42 0
|
6月前
19.3 Boost Asio 多线程通信
多线程服务依赖于两个通用函数,首先`boost::bind`提供了一个高效的、简单的方法来创建函数对象和函数对象适配器,它的主要功能是提供了一种将函数和它的参数绑定到一起的方法,这种方法可以将具有参数的成员函数、普通函数以及函数对象转化为不带参数的函数对象。当参数绑定后则下一步就需要使用多线程功能,Boost库中提供了`boost::thread`库,`boost::thread`可以用于创建线程、启动线程、等待线程执行结束以及线程间通信等多种操,有了这两个关键库那么我们只需要`accept.accept(*sock)`等待套接字上线,当有套接字上线后则自动创建`MyThread`子线程,
49 0
19.3 Boost Asio 多线程通信
|
21天前
|
安全 Java 编译器
【JavaEE多线程】线程安全、锁机制及线程间通信
【JavaEE多线程】线程安全、锁机制及线程间通信
33 1
|
5月前
|
安全 Java 数据库连接
详细介绍线程间通信
详细介绍线程间通信 线程间通信是指在多线程编程中,不同的线程之间通过某种方式交换信息的过程。这是一个重要的概念,因为线程之间的协作是实现复杂并发系统的关键。 下面是一些线程间通信的常见方式和示例:
398 0
|
安全 Java 容器
高并发编程之线程间通信和集合的线程安全
高并发编程之线程间通信和集合的线程安全
24 1
|
2月前
|
消息中间件 并行计算 网络协议
探秘高效Linux C/C++项目架构:让进程、线程和通信方式助力你的代码飞跃
探秘高效Linux C/C++项目架构:让进程、线程和通信方式助力你的代码飞跃
41 0
|
2月前
|
存储 Java 数据库连接
线程通信(CountDownLatch、CyclicBarrier、Semaphore、Exchanger)
线程通信(CountDownLatch、CyclicBarrier、Semaphore、Exchanger)
35 0

相关实验场景

更多