信号量

Posted 小荷才楼尖尖角

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了信号量相关的知识,希望对你有一定的参考价值。

信号量的主要目的是提供一种进程间同步的方式。

信号量有两种: 有名信号量和无名信号量。无名信号量也被称作基于内存的信号量。 有名信号量通过IPC名字进行进程间的同步,而无名信号量如果不是放在进程间的共享内存区中,是不能用来进行进程间同步的,只能用来进行线程间同步。

信号量有三种操作:

1. 创建一个信号量。创建的过程还要求初始化信号量的值。

     根据信号量取值(代表可用资源的数目)的不同,POSIX信号量还可以分为:

  • 二值信号量:信号量的值只有0和1,类似于互斥量,若资源被锁住,信号量的值为0,若资源可用,则信号量的值为1。
  • 计数信号量:信号量的值在0到一个大于1的限制值(POSIX指出系统的最大限制值至少要为32767)。该计数表示可用资源的个数。

2. 等待一个信号量(wait)。该操作会检查信号量的值,如果其值小于或等于0,那就阻塞,直到该值变成大于0,然后等待进程将信号量的值减1,进程获得共享资源的访问权限。这整个操作必须是一个原子操作。该操作还经常被称为P操作(荷兰语Proberen,意为:尝试)。

3. 挂出一个信号(post)。该操作将信号量的值加1,如果有进程阻塞着等待该信号量,那么其中一个进程将被唤醒。该操作也必须是一个原子操作。该操作还经常被称为V操作(荷兰语Verhogen,意为:增加)。

 

信号量函数接口

1. 有名信号量的创建和删除

1 #include<semaphore.h>
2 
3 sem_t *sem_open(const char *name, int oflag);
4 sem_t *sem_open(const char*name, int oflag, mode_t mode, unsigned int value); // 成功返回信号量指针,失败返回SEM_FAILED

sem_open用于创建或打开一个信号量,信号量是通过name参数即信号量的名字来进行标识的。

oflag参数可以为0,O_CREAT,O_EXCL。如果为0表示打开一个已存在的信号量,如果为O_CREAT表示如果信号量不存在就创建一个信号量,如果存在则打开并返回。此时mode和value需要指定。如果为O_CREAT|O_EXCL,表示如果信号量已存在会返回错误。

mode参数用于创建信号量时,表示信号量的权限位,和open函数一样包括:S_IRUSR, S_IWUSR,S_IRGRP,S_IWGRP,S_IROTH, S_IWOTH。

value表示创建信号量时,信号量的初始值。

1 #include <semaphore.h>
2 
3 int sem_close(sem_t *sem);
4 int sem_unlink(const char *name); // 成功返回0,失败返回-1

sem_close用于关闭打开的信号量。当一个进程终止时,内核对其上仍然打开的所有有名信号量自动执行这个操作。调用sem_close关闭信号量并没有把它从系统中删除它,有名信号量是随内核持续的。即使当前没有某个进程打开某个信号量它的值依然保持。直到内核重新自举或调用sem_unlink()删除该信号量。

sem_unlink用于将有名信号量立刻从系统中删除,但信号量的销毁是在所有进程都关闭信号量的时候。

 

2. 信号量的P操作 

1 #include<semaphore.h> 
2 int sem_wait(sem_t *sem);//成功返回0,失败返回-1

sem_wait()用于获取信号量,首先会测试指定信号量的值,如果大于0,就会将它减1并立即返回,如果等于0,那么调用线程会进入睡眠,指定信号量的值大于0。

 

3. 信号量的V操作

1 #include<semaphore.h>
2 int sem_post(sem_t *sem); //成功返回0,失败返回-1

 当一个线程使用完某个信号量后,调用sem_post,使该信号量的值加1,如果有等待的线程,那么会唤醒等待的线程。

 

4. 获取当前信号量的值

1 #include<semaphore.h>
2 int sem_getvalue(sem_t *sem, int *sval); //成功返回0,失败返回-1

该函数返回当前信号量的值,通过sval输出参数返回,如果当前信号量已经上锁(即同步对象不可用),那么返回值为0,或为负数,其绝对值就是等待该信号量解锁的线程数。

以上是关于信号量的主要内容,如果未能解决你的问题,请参考以下文章

窗函数介绍

谱分析中窗的选取

Android MediaPlayer AudioStream AudioFlinger 服务器死机!,致命信号 11

傅里叶变换滤波之生物信号滤波(笔记03)

Android webview 崩溃“致命信号 5 (SIGTRAP)”

找到信号的基频