一、IPC (Inter-Process Communication): --中文翻译是线程间的通信消息队列共享内存(效率最高)信号灯集
二、客户端命令:ipcs:--用来查看system V的IPC机制标识符的命令
-q,显示当前系统中 消息队列 的使用
-m,显示当前系统中 共享内存 的使用
-s, 显示当前系统中 信号量 的使用
ipcrm:--用来删除 当前系统中 system V的IPC机制标识符的命令
-q,删除当前系统中 消息队列的标识符
-m,删除当前系统中 共享内存的标识符
-s,删除当前系统中 信号灯集的标识符
比如:
ipcrm -m 共享内存的id
三、具体:
消息队列:--消息队列可以看做是若干个FIFO的集合,每个FIFO存放不同类型的消息。1. msgget 消息队列的创建、打开
2. msgsnd 往消息队列中写消息
3. msgrcv 读取消息或接收一条消息
4. msgctl 控制函数(获取、设置、删除)
1. msgget:消息队列的创建、打开包含的库:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
函数原型:
int msgget(key_t key, int msg**);
参数:
①key,ftok获得的值
②msg**,
IPC_CREAT,创建
IPC_EXCL ,有错误,就提醒
返回值:
消息队列的标识符。
例子:
msgget(key, IPC_CREAT|TPC_EXCL|0666);
2. msgsnd: --往消息队列中写消息包含库:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
函数原型:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msg**);
参数:
①msqid,要操作的消息队列的标识符
②msgp,存放要发送的消息。
定义要求:
struct msgbuf {
long mtype; /* 消息的类型, must be > 0 */
char mtext[1]; /* message data */
};
③msgsz,发送的消息的正文的长度(除去消息类型之外的)。
sizeof(struct msgbuf) - sizeof(long);
④msg**,决定了消息的发送是否是阻塞方式
IPC_NOWAIT,非阻塞
0,阻塞,直到发送成功
返回值:
成功 0
失败 -1
3. msgrcv: --读取消息或接收一条消息头文件:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
函数原型:
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msg**);
参数:
①msqid,要读取的消息队列
②msgp,接收消息的缓冲区
定义要求:
struct msgbuf {
long mtype; /* 消息的类型, must be > 0 */
char mtext[1]; /* message data */
};
③msgsz,要接收消息的正文的长度
④msgtyp,要读取的消息队列中消息的类型
0,表示读取消息队列中的第一条消息
>0,表示读取消息队列中类型为msgtype的消息
<0,接收消息队列中类型值不小于msgtyp 的绝对值且类型值又最小的消息。
⑤msg**,决定了消息的接收是否是阻塞方式 IPC_NOWAIT,非阻塞
0,阻塞,直到有对应的消息
返回值:
成功 读到消息正文的字节个数
失败 -1
4. msgctl: --控制函数库:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
原型:
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数:
msgid,要操作的消息队列的标识符
cmd,
IPC_STAT (获取对象属性), 存放在第三参数中
IPC_SET (设置对象属性),第三个参数存放将要设置的属性
IPC_RMID (删除对象), 此时第三个参数为NULL。
返回值:
成功,0
失败,-1
__________________________________________________________________________________________
共享内存:ftok
2. shmget 创建/打开共享内存
3. shmat 获得一个共享内存的映射地址
4. shmdt 接触映射
5. shmctl 共享内存的控制(获取、设置、删除)
1. ftok:--获得一个key值包括的库:
#include <sys/types.h>
#include <sys/ipc.h>
函数原型:
key_t ftok(const char *pathname, intproj_id);
参数:
pathname,文件名
proj_id,是子序号。虽然是int类型,但是只使用8bits(1-255)
例子:
2. shmget:--创建/打开共享内存包含库:
#include <sys/ipc.h>
#include <sys/shm.h>
函数原型:
int shmget(key_tkey, size_tsize, int shm**);
参数:
①key, 用来使不同进程使用相同的共享内存,键值用来区分不同的共享内存
IPC_PRIVATE:表示申请的共享内存是私用的。
key = ftok(xxx); 需要通过ftok函数来获得。
②size:进程要申请的共享内存的大小(字节)
③shm**:
IPC_CREAT,创建
IPC_EXCL,如果有错误,指出
指定的共享内存的权限:IPC_CREAT|IPC_EXCL| 0666
返回值:
成功,返回 获得的共享内存的标识符。
失败, 返回 -1.
用法:
int shmid;
key = ftok(&quot;.&quot;, 'a');
shmid = shmget(key, 1000,IPC_CREAT|IPC_EXCL|0666); 创建
shmid = shmget(key, 1000,0666)打开共享内存:
3. shmat: --获得一个共享内存的映射,返回一个指向共享内存的指针,函数原型:
void *shmat(intshmid, const void *shmaddr, int shm**);
参数:
①shmid,共享内存标识符
②shmaddr,为 NULL表示让系统为用户自动分配内存
非NULL 用户自定义空间
③shm**,
SHM_RDONLY 表示对共享内存的操作,只可以读。
0 表示可读可写
返回值:
成功,返回映射后的地址。需要强制类型转换
失败,返回NULL。
4. shmdt:--解除映射。 函数原型:
int shmdt(const void *shmaddr);
参数:
就是shmat的返回值
返回值:
0,成功
-1,失败
5. shmctl:--共享内存的控制函数 包含头文件:
#include <sys/shm.h>
函数原型:
int shmctl(intshmid, intcmd, struct shmid_ds *buf);
参数:
①shmid: 要操作的共享内存的标识符
②cmd:
IPC_STAT (获取对象属性), 存放在第三参数中
IPC_SET (设置对象属性),第三个参数存放将要设置的属性
IPC_RMID (删除对象), 此时第三个参数为NULL。
返回值:
0,成功
-1,失败
__________________________________________________________________________________________
信号量:--也叫system V的信号灯集: 一种计数信号灯1. semget 创建/打开一个信号量 集合
2. semctl 对信号量的集合的控制
3. semop 信号量集合的 PV 操作
1. semget: --创建/打开一个信号灯集合库:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
原型:
int semget(key_tkey, intnsems, int sem**);
参数:
①key,ftok获得值
②nsems,表示要申请的信号灯集合中包含的信号量的个数
③sem**,
IPC_CREAT
IPC_EXCL
例子:
semget(key, 2, IPC_CREAT|IPC_EXCL|0666);
返回:
成功,返回一个信号灯集合的标识符 -->是 semid
失败 -1
2. semctl: --对信号灯集合的控制库:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
原型:
int semctl(intsemid, intsemnum, int cmd, ...);
参数:
①semid,
②semnum,要操作该集合中信号量的编号,信号量的编号从0开始。
③cmd,
GETVAL,获取信号灯的值
SETVAL,设置信号灯的值 semctl(semid, 0, SETVAL, 共用体);
IPC_RMID,从系统中删除信号灯集合 semctl(semid, 0, IPC_TMID);--随便删除哪一个,都能把所有的删除
④第四个参数,看命令字需要不需要,且内容可以是一个和多个
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) */
};
返回值:
成功 0
失败 -1
3. semop: --信号灯集合的 PV 操作库:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
原型:
int semop(int semid, struct sembuf *opsptr, size_tnops);
参数:
①semid,
②opsptr,
struct sembuf{ --注意,这个结构体不需要自己定义,可直接用
unsigned short sem_num; /* semaphore number */ //要操作的信号量的编号
short sem_op; /* semaphore operation */ //要执行的PV操作
short sem_**; /* operation flags */
};
sem_num成员,要操作的信号量的编号
sem_op成员,
0等待,直到信号灯的值变成0
>0,表示信号量的值要增加 semop 个,相当于V
<0,表示信号量的值要减少 semop 个,相当于P
sem_flag,
0,semop函数阻塞操作
IPC_NOWAIT,非阻塞,,,
SEM_UNDO(不常用),
③nops,semop函数执行一次要操作的
返回值:
成功 0
失败 -1
通信 |
|