无名信号量

POSIX标准提出了有名信号量和无名信号量来同步进程和线程,而linux(2.6以前)只实现了无名信号量。

sem_overview中有详细介绍:man 7 sem_overview.

System V semaphores(semget, segop, etc.)是旧的信号量API,但应用广泛。 posix信号量简单易用。

命令行ipcs可提供ipc相关信息,如显示调用进程的信号灯,ipcs -s。

  • Posix Sem
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);
int sem_getvalue(sem_t *sem);

pshared决定了信号量是否在几个进程间共享,0信号量在线程间共享;非0表信号量在进程间共享.

编译上面几个函数程序要加上-lrt选项,以连接the real-time library, librt.so库。

加锁步骤:值大于0,值减1,锁成功;值小于等于0,则锁不成功阻塞。

解锁步骤:值加1,唤醒所有阻塞线程。

  • System sem
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
key_t ftok(char *pathname, int proj);
int semget(key_t key, int nsems, int semflg);
int semctl(int semid, int semnum, int cmd, union semun arg);  // semnum指出感兴趣的特定信号灯。
int semop(int semid, struct sembuf *spos, int nspos);  //nspos为spos指向的数组的元素个数

struct sembuf{
    short sem_num; /*使用哪一个信号*/  
    short sem_op; /*进行什么操作*/
    short sem_flg; /*操作的标志*/    
};

sembuf结构中,sem_num是信号灯的编号,其值从0到nsems-1,sem_op是执行的操作,而sem_flg调整semop的行为。sem_op能够为正值、负值和0。
>>如果sem_op为正,信号灯控制的资源被释放,而且信号灯的值增加。
>>如果sem_op为负,调用进程表示它将等待直到受控资源被释放,此时信号灯的值减小而资源被调用进程加锁。
>>如果sem_op为0,调用进程阻塞直到信号灯变为0;如果信号灯已经是0,调用立即返回。
sem_flg可以为IPC_NOWAIT,不等待直接返回,或者SEM_UNDO,这意味着当调用semop的进程退出后执行的操作将被撤销。 cmd可以取值:GETVAL,SETVAL,GETPID,GETNCNT(在信号灯上等待的进程数),GETZCNT(等待信号灯的值为0的进程数),GETALL,SETALL,
IPC_RMID(删除带有semid的信号灯),IPC_SET(在信号灯上设置模式--权限位), IPC_STAT(每个信号灯都有一个数据结构semid_ds,
这个数据结构完整地描述它的配置和行为。IPC_STAT把这些配置信息复制到semun结构的成员arg.buf中) 创建信号量集
The semget() system call returns the semaphore set identifier associated with the argument key. A new set of nsems semaphores is created
if key has the value IPC_PRIVATE or if no existing semaphore set is associated with key and IPC_CREAT is specified in semflg.
If  semflg  specifies both IPC_CREAT and IPC_EXCL and a semaphore set already exists for key, then semget() fails with errno set to EEXIST.  
(This is analogous to the effect of the combi‐nation O_CREAT | O_EXCL for open(2).)
假如指定参数key为IPC_PRIVATE,或与key相关的信号集不存在且semflg为IPC_CREAT,则信号集被创建。
If successful, the return value will be the semaphore set identifier (a nonnegative integer), otherwise -1 is returned, with errno indicating the error.
创建key
ftok - convert a pathname and a project identifier to a System V IPC key
The ftok() function uses the identity of the file named by the given pathname (which must refer to an existing, accessible file)
and the least significant 8 bits of proj_id (which must be nonzero) to generate a key_t type System V IPC key, suitable for use with msgget(2), semget(2), or shmget(2).
The resulting value is the same for all pathnames that name the same file, when the same value of proj_id is used.
The value returned should be different when the (simultaneously existing)files or the project IDs differ.
On success, the generated key_t value is returned. On failure -1 is returned, with errno indicatine the error as for the stat(2) system call.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h> int main(void)
{
int semid;
int nsems = ;
int flags = ;
struct sembuf buf; semid = semget(IPC_PRIVATE, nsems, flags);
if(semid < )
{
perror("semget");
exit(EXIT_FAILURE);
}
printf("semaphore created: %d\n", semid); buf.sem_num = ;
buf.sem_op = ;
buf.sem_flg = IPC_NOWAIT; if((semop(semid, &buf, nsems)) < )
{
perror("semop");
exit(EXIT_FAILURE);
} system("ipcs -s");
exit(EXIT_SUCCESS);
}
多次运行结果如下:
~$./a.out
semaphore created: ------ Semaphore Arrays --------
key semid owner perms nsems
0x00000000 yu
0x00000000 yu
0x00000000 yu
0x00000000 yu
0x00000000 yu

include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>
#include <stdlib.h> int main(int argc, char **argv)
{
int semid; if(argc != )
{
puts("USAGE: sctl <semaphore id>");
exit(EXIT_FAILURE);
}
semid = atoi(argv[]); if((semctl(semid, , IPC_RMID)) < )
{
perror("semctl IPC_RMID");
exit(EXIT_FAILURE);
} else {
puts("semaphore removed");
system("ipcs -s");
} exit(EXIT_SUCCESS);
}
~$./a.out
USAGE: sctl <semaphore id>
~$./a.out
semaphore removed ------ Semaphore Arrays --------
key semid owner perms nsems
0x00000000 yu
0x00000000 yu
0x00000000 yu
0x00000000 yu
主要应用于保护临界资源(同一时刻只有一个进程可以访问资源)。

IPC之信号量的更多相关文章

  1. System V IPC 之信号量

    本文继<System V IPC 之共享内存>之后接着介绍 System V IPC 的信号量编程.在开始正式的内容前让我们先概要的了解一下 Linux 中信号量的分类. 信号量的分类 在 ...

  2. Linux IPC 之信号量

    信号量(也叫信号灯)是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语. 信号量是进程/线程同步的一种方式,有时候我们需要保护一段代码,使它每次只能被一个执行进程/线程运行,这种工作就需 ...

  3. IPC进程间通信---信号量

    信号量 信号量:信号量是一个计数器,常用于处理进程或线程的同步问题,特别是对于临界资源访问的同步.临界资源可以 理解为在某一时刻只能由一个进程或线程操作的资源,这里的资源可以是一段代码.一个变量或某种 ...

  4. linux IPC的信号量

    信号量相关函数原型 获得一个信号量ID #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h&g ...

  5. OS: 生产者消费者问题(二) ---- 系统V IPC通信-信号量和共享内存

    在上一篇“OS: 生产者消费者问题(多进程+共享内存+信号量)”中提到的方法二: 如果进程之间并没有父子关系,但是协商好了共享存储的 KEY , 那么在每个进程中,就可以通过 KEY 以及 shmge ...

  6. IPC之——信号量集(多个信号量)

    如果两个进程不仅需要同步,还要保证先后执行顺序,就要用两个信号量(互斥锁)来解决 //栅栏模型:实现以下框架中的四个子进程 所有进程做完任务后 在一起执行下一次  #include <stdio ...

  7. IPC之——信号量集

    信号量集用于对存在竞争的资源加锁 1.semId=semget(key,nsems,semflg) key:为信号量集名称,可以指定为0455等数字,也可以为PC_PRIVATE nsems:创建几个 ...

  8. Linux IPC POSIX 信号量

    模型 #include<semaphore.h> #include<sys/stat.h> #include<fcntl.h> sem_open() //初始化并打 ...

  9. System V IPC(2)-信号量

    一.概述                                                    System V信号量与System V消息队列不同.它不是用来在进程间传递数据.它主要 ...

随机推荐

  1. JS夯实基础:Javascript 变态题解析 (上)

    ["].map(parseInt) 1.知识点: Array/map Number/parseInt Global_Objects/parseInt JavaScript parseInt ...

  2. IP地址转换、主机大小端、htonl、ntohl实现

    copy   #include <IOSTREAM> //#include <WINSOCK.H> using std; typedef  uint16; unsigned   ...

  3. How to publish a WordPress blog to a static GitLab Pages site

    https://opensource.com/article/18/8/publish-wordpress-static-gitlab-pages-site A long time ago, I se ...

  4. [Angular] AfterContentChecked && AfterViewChecked

    AfterContentChecked & AfterViewChecked are called after 'OnChanges' lifecycle. And each time 'ng ...

  5. 安装Tomcat指定JDK ——转

    转自:http://www.cnblogs.com/lioillioil/archive/2011/10/08/2202169.html 一.应用实例 一般情况下一台服务器只跑一个业务,那么就直接配置 ...

  6. IBATIS+ORACLE(一)

      迁移时间:2017年6月1日15:55:17 Author:Marydon (四)IBATIS + ORACLE 第一部分:基础篇 1.4.1.1 分页SQL <!-- 开头 --> ...

  7. 将项目从tomcat 迁移到JBoss5.0

    http://java-boy.iteye.com/blog/531411从Tomcat升级到JBoss5.1真是一个痛苦的过程,可能遇到很多问题.以下是我碰到的问题,及解决方法. 一.Hiberna ...

  8. Ubuntu 安装配置 JDK+Tomcat+Nginx

    安装配置JDK 下载安装 # 下载: wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=acc ...

  9. python selenium --处理下拉框

    下拉框是我们最常见的一种页面元素,对于一般的元素,我们只需要一次就定位,但下拉框里的内容需要进行两次定位,先定位到下拉框,再定位到下拉框内里的选项. drop_down.html <html&g ...

  10. Hive 数据倾斜原因及解决方法(转)

    在做Shuffle阶段的优化过程中,遇到了数据倾斜的问题,造成了对一些情况下优化效果不明显.主要是因为在Job完成后的所得到的Counters是整个Job的总和,优化是基于这些Counters得出的平 ...