IO进程 day08

11. 进程间的通信机制

11.6. 信号灯集

概念

 信号灯,又叫信号量,是不同进程或同一个进程的不同线程间的同步机制
 System V信号灯集是一个或者多个信号灯的集合。其中每一个都是单独的信号灯,Posix信号灯是单个的计数信号灯
 通过信号灯可以同步共享内存的同步

步骤

  1. 创建key——ftok
  2. 创建或打开信号灯集——semget
  3. 初始化信号灯集——semctl
  4. PV操作——semop
  5. 删除信号灯——semctl

semget

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);

功能:创建信号灯集
参数:
key_t keykey值
int nsems信号灯集里的信号灯的数目
int semflg信号灯集的访问权限,一般为IPC_CREAT | IPC_EXCL | 0666
返回值:成功返回信号灯集ID,失败返回EOF

semctl

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl ( int semid, int semnum,int cmd,…/*union semun arg*/);

功能:操作信号灯集
参数:
int semid信号灯集ID
int semnum要操作的信号灯的编号
int cmd对信号灯的操作

宏名操作
GETVAL获得信号灯的值
IPC_RMID从系统中删除信号灯集
SETVAL设置信号灯的值

union semun arg信号灯的共用体,需要自己定义,只有在第三个参数为SETVAL时,才需要输入该参数
返回值:
 成功返回0,当第三个参数为GETVAL时,返回值是信号灯的值
 失败返回EOF;
注意
共用体如下

union semun
{
	int val;	// 信号灯的初值
	// struct semid_ds *buf;
	// unsigned short  *array;
	// struct seminfo  *__buf;
}

semop

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop ( int semid, struct sembuf  *opsptr,  size_t  nops);

功能:对信号灯集中的信号量进行申请和释放
参数:
int semid信号灯集ID
struct sembuf *opsptr操作方式,需要&结构体
size_t nops需要操作的信号灯个数:1个
返回值:成功返回0,失败返回EOF
注意
操作的结构体如下

struct sembuf
{
	short sem_num;	// 需要操作的信号灯编号
	short sem_op;	// 对信号灯的操作,+1释放V,-1申请P
	short sem_flg;	// 0:阻塞
}

初始化和操作信号灯函数封装

void seminit (int semid, int num, int val)
{
	union semun sem;
	sem.val = val;
	semctl(semid, num, SETVAL, sem);
}

void sem_op (int semid, int op, int num)
{
	struct sembuf buf;
	buf.sem_num = num;
	buf.sem_op = op;
	buf.sem_flg = 0;
	semop(semid, &buf, 1);
}

命令

ipcs -s		#查看信号灯集
ipcrm -s [semid]	#删除信号灯集

11.7. 消息队列

特点

  1. 消息队列就是一个消息列表
  2. 消息队列可以实现消息的添加,读取等操作
  3. 消息队列按照类型来收发消息
  4. 消息队列在Linux系统中有大小限制
类别大小限制
消息队列个数16个
消息队列总容量16k
每个消息的内容8k

步骤

  1. 创建key——ftok
  2. 创建或打开消息队列——msgget
  3. 添加消息——msgsnd
  4. 读取消息——msgrcv
  5. 删除消息队列——msgctl

msgget

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int flag);

功能:创建消息队列
参数:
key_t keykey值
int flag访问权限,一般为IPC_CREAT | IPC_EXCL | 0666
返回值:成功返回msgid,失败返回EOF

msgsnd

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t size, int flag); 

功能:添加消息
参数:
int msqid消息队列的ID
const void *msgp指向消息的指针
size_t size发送消息正文的字节数
int flag
   IPC_NOWAIT消息没有发送完成函数也会立即返回
  0:直到发送完成函数才返回
返回值:成功返回0,失败返回EOF
注意

  1. 消息的结构如下,需要自行定义
struct msgbuf
{
	long mtype;		//消息类型
	char mtext;		// 消息正文,正文的类型不限
}
  1. 变量mtype必须是long类型的,而且必须在第一个,且大于0
  2. 参数:size_t size是正文的大小,不算mtype直接用结构体大小-mtype的大小

msgrcv

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int msgid,  void* msgp,  size_t  size,  long msgtype,  int  flag);

功能:读取消息
参数:
int msqid消息队列的ID
void *msgp指向消息的指针
size_t size发送消息正文的字节数
long msgtype接收消息队列中类型为msgtype的消息
int flag
   IPC_NOWAIT没有消息立即返回ENOMSG
  0:没有消息就一直阻塞
返回值:成功返回收到的消息的长度,失败返回EOF

msgctl

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

功能:删除消息队列
参数:
int msgqid消息队列的ID
int cmd写入IPC_RMID:从系统中删除消息队列
struct msqid_ds *buf消息队列缓冲区,一般为NULL
返回值:成功返回0,失败返回EOF

命令

ipcs  -q	#查看创建的消息队列
ipcrm  -q  [msqid]	#删除消息队列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值