Linux学习系列(十二):进程间通信--信号量

目录:

3.信号量

  • 命令
ipcs //查看消息队列、信号量、共享内存
    
ipcrm -s semid //删除信号量 semid是信号量的ID

  • 信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目,只是一种同步机制,不能实现进程间的数据共享

  • 获取资源时,需要对信号量的值进行原子减一,该操作被称为 P 操作。当信号量值为 0 时,代表没有 资源可用,P 操作会阻塞

  • 释放资源时,需要对信号量的值进行原子加一,该操作被称为 V 操作。信号量主要用来同步进程。信号量的值如果只取 0,1,将其称为二值信号量。如果信 号量的值大于 1,则称之为计数信号量。

  • 临界资源:同一时刻,只允许被一个进程或线程访问的资源

  • 临界区:访问临界资源的代码段

  • 信号量:多个进程 访问相同资源 冲突 红绿灯

  • 特殊的变量 值>= 0 值可用资源的数目
    试衣间: 3个 信号量值: 3

  • API接口函数介绍

#include <sys/sem.h>
#include <sys/types.h>
#include <sys/ipc.h>

//semget()创建或者获取已存在的信号量
int semget(key_t key, int nsems, int semflg);
/*	
	semget()成功返回信号量的 ID, 失败返回-1
	key:两个进程使用相同的 key 值,就可以使用同一个信号量
	nsems:内核维护的是一个信号量集,在新建信号量时,其指定信号量集中信号量的个数
	semflg 可选: IPC_CREAT IPC_EXCL												
*/


//semop()对信号量进行改变,做 P 操作或者 V 操作
int semop(int semid, struct sembuf *sops, unsigned nsops);
/* 	
	semop()成功返回 0,失败返回-1
	struct sembuf
	{
		unsigned short sem_num; //指定信号量集中的信号量下标
		short sem_op; //其值为-1,代表 P 操作,其值为 1,代表 V 操作
		short sem_flg; //SEM_UNDO   IPC_NOWAIT 一般信号量为0,p操作阻塞,使用该则不阻塞返回一个错误
	}; 		 
    nsops sembuf结构体数组的大小													
*/


//semctl()控制信号量
int semctl(int semid, int semnum, int cmd, ...);
/*	
	semctl()成功返回 0,失败返回-1
	cmd 选项: SETVAL(初始化) IPC_RMID(删除)
	union semun
	{
		int val;
		struct semid_ds *buf;
		unsigned short *array;
		struct seminfo *_buf;
	};																				
*/
#include "sem.h"   //sem.c

static int semid; //静态全局变量 --- .data区    本文件有效

void sem_init(){
    semid = semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);    //1234编号 1:1个信号量
    if(semid == -1){ // 创建失败(只需要获取)
        semid = semget((key_t)1234,1,0600); //获取
        if(semid == -1) exit(1);
    }
    else{
        union semun a;
        a.val = 1;
        if(semctl(semid,0,SETVAL,a) == -1){  //0号下标
            perror("semctl error");
            exit(1);
        }
    }
}
void sem_p(){
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = -1;  //获取资源
    buf.sem_flg = SEM_UNDO;

    if(semop(semid,&buf,1) == -1){
        perror("semop err");
        exit(1);
    }
}
void sem_v(){
    struct sembuf buf;
    buf.sem_num = 0;
    buf.sem_op = 1;  //释放资源
    buf.sem_flg = SEM_UNDO;

    if(semop(semid,&buf,1) == -1){
        perror("semop err");
        exit(1);
    }
}
void sem_destory(){
    if(semctl(semid,0,IPC_RMID) == -1){
        perror("semctl rm  error");
        exit(1);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lijiachang030718

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值