IO进程 day08

IO进程 day08

  • 11. 进程间的通信机制
    • 11.6. 信号灯集
      • 概念
      • 步骤
      • semget
      • semctl
      • semop
      • 初始化和操作信号灯函数封装
      • 命令
    • 11.7. 消息队列
      • 特点
      • 步骤
      • msgget
      • msgsnd
      • msgrcv
      • msgctl
      • 命令

11. 进程间的通信机制

11.6. 信号灯集

概念

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

步骤

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

semget

#include 
#include 
#include 
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 
#include 
#include 
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 
#include 
#include 
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 
#include 
#include 
int msgget(key_t key, int flag);

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

msgsnd

#include 
#include 
#include 
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 
#include 
#include 
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 
#include 
#include 
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]	#删除消息队列

你可能感兴趣的:(Linux阶段四:IO进程,c语言,IO进程,linux)