本期主要分享的是进程间通信的最后两种通信方式:消息队列和共享内存,其中包括ftok,msgget,msgsnd,msgrcv,msgctl,shmget,shmat,shmdt,shmctl等;
进程间通信: 管道: 信号:
(1)消息队列 SYS V(系统五分支)
(2)共享内存
(3)信号灯
(1)套接字 BSD(分支)
一、消息队列:
IPC对象:内存文件
1.命令:
ipcs 查看IPC对象信息
ipcrm -M/-Q/-S key
ipcrm -m/-q/-s id
key:ipc对象名称
msgid:消息队列id号
shmid:共享内存id号
semid:信号灯的id号
2.函数接口:
(1)ftok
key_t ftok(const char *pathname, int proj_id);
功能:
生成一个IPC对象名称
参数:
pathname:目录路径
proj_id:项目ID(一般传一个字符)
返回值:
成功返回key值
失败返回-1
(2)msgget
int msgget(key_t key, int msgflg);
功能:
创建一个消息队列
参数:
key:IPC对象名称
msgflg:
IPC_CREAT 创建IPC对象
IPC_EXCL 检测IPC对象是否存在
返回值:
成功返回消息队列id
失败返回-1
(3)msgsnd
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:
向消息队列中写入消息(发送消息)
参数:
msqid:消息队列id号
msgp:发送消息空间首地址
msgsz:消息的长度
msgflg:消息的属性默认为0
返回值:
成功返回0
失败返回-1
消息队列数据格式:
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
(4)msgrcv
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
功能:
从消息队列中接收消息
参数:
msqid:消息队列ID号
msgp:存放消息队列数据空间首地址
msgsz:消息队列内容大小
msgtyp:消息队列类型
msgflg:接收消息属性,默认为0
返回值:
成功返回接收消息内容的字节数
失败返回-1
(5)msgctl
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:
控制消息队列
参数:
msgqid:消息队列ID号
cmd:消息类型
IPC_STAT 获得IPC状态
IPC_SET 设置IPC权限
IPC_RMID 删除
返回值:
成功返回0
失败返回-1
二、共享内存:
进程间通信最高效的形式
1.特点:
1.不需要对数据进行收发
2.两个进程将地址映射到同一片空间,对数据存取即可实现通信
2.操作步骤:
1.创建key值
2.创建共享内存
3.映射到共享内存
4.对数据存取
5.解除映射
6.删除共享内存
3.函数:
(1)ftok
(2)shmget
int shmget(key_t key, size_t size, int shmflg);
功能:
创建共享内存
参数:
key:IPC对象名称
size:共享内存大小
shmflg:
IPC_CREAT 创建
IPC_EXCL 监测是否存在
返回值:
成功返回共享内存ID
失败返回-1
(3)shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:
映射地址到共享内存空间中
参数:
shmid:共享内存id号
shmaddr:
NULL 让系统选择一个合适的地址映射
shmflg:
默认为0
返回值:
成功返回映射到共享内存空间中的地址
失败返回NULL
(4)shmdt
int shmdt(const void *shmaddr);
功能:
解除映射
参数:
shmaddr:共享内存空间首地址
返回值:
成功返回0 失败返回-1
(5)shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:
向共享内存发送一个命令
参数:
shmid:共享内存ID号
cmd:
IPC_STAT 获得共享内存属性
IPC_SET 设置共享内存属性
IPC_RMID 删除共享内存
buf:
操作对象空间首地址
返回值:
成功返回0
失败返回-1
三、信号灯:
一组信号量,信号量数组,实现同步
1.函数:
(1)ftok (首先也是ftok)
(2)semget
int semget(key_t key, int nsems, int semflg);
功能:
创建一个信号量数组
参数:
key:键值
nsems:信号量数组元素个数(信号量个数)
semflg:
IPC_CREAT
返回值:
成功返回信号灯id
失败返回-1
(3)semctl
int semctl(int semid, int semnum, int cmd, ...);
功能:
向信号量发送一个命令
参数:
semid:信号量id
semnum:信号量的下标
cmd:
IPC_RMID:删除共享内存
SETVAL:设置信号的值
返回值:
成功返回0
失败返回-1
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
(4)semop
int semop(int semid, struct sembuf *sops, size_t nsops);
功能:
操作信号量
参数:
semid:信号量ID号
sops:信号量操作数组的首地址
nsops:信号量操作数组个数
返回值:
成功返回0
失败返回-1
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */