进程间的通信---(二)信号量

来源:互联网 发布:始于颜值…网络完整版 编辑:程序博客网 时间:2024/06/05 17:20

信号量

首先了解几个基本概念 

1、临界资源:在同一时刻只能被一个进程访问。例如我们现实生活中的打印机,取款机等等

–硬件资源(处理器、内存、存储器以及其他外围设备等)

–软件资源(共享代码段,共享结构和变量等)

2、临界区:访问临界资源代码

3、原子操作:不能被打断的操作

4、内核对象:就是维护对象保存对象信息的数据结构

信号量:进程间的同步控制(详见文章进程的同步与异步),可以控制仿临界资源,记录资源能被访问的个数

与锁的区别:锁一旦锁住不可修改,信号量被使用后在某种条件下还可以再次使用,例如我信号量的值为2,进行减一操作,此时信号量的值为1,还可以进行减一操作

信号量的使用

创建:调用semget()函数创建信号量集,用semctl()SETVAL操作对其进行初始化。如果是创建,必须初始化,如果获取,则不能初始化

减一操作:p操作,使用semctl()函数

加一操作:V操作,使用semop()函数

删除操作:使用semctl()  IPC_RMID操作

函数使用详解








操作函数的实现

sem.h文件

#ifndef __SEM_H#define __SEM_H#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <assert.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>int semid;union semun{    int val;};void sem_init(); //创建或者获取信号量void sem_p();  //P操作void sem_v();  //V操作void sem_destory(); //删除#endif
sem.c文件

#include"sem.h"      void sem_init(){    semid=semget((key_t)1234,1,0664);//得到信号量集标识符    if(semid==-1)//如果获取失败创建一个新的信号量集    {        semid=semget((key_t)1234,1,0664|IPC_CREAT);        assert(semid!=-1);    }    union semun a;//定义一个联合体用来初始化信号量    a.val=0;//给联合体的有效值赋值,这个值后面会附给信号量    if(semctl(semid,0,SETVAL,a)==-1)    {        perror("error");        exit(0);    }}
void sem_p()//减一操作{    struct sembuf buff;    buff.sem_num = 0;    buff.sem_op = -1;//pv操作改变的核心就是op的值,-1为p操作,0为v操作    buff.sem_flg = SEM_UNDO;     if(-1 == semop(semid, &buff, 1))      {          perror("p error");         exit(0);      }}void sem_v(){  struct sembuf buff;  buff.sem_num = 0;  buff.sem_op = 1;  buff.sem_flg = SEM_UNDO;  if(-1 == semop(semid, &buff, 1)) {    perror("p error");    exit(0);  }}void sem_destory(){    if(semctl(semid,0,IPC_RMID)==-1)//设置为semctl的IPC_RMID模式    {      perror("error");      exit(0);    }}

 
原创粉丝点击