1.共享内存:
1.进程间通信最高效的形式
不需要实现数据收发,只需要两个进程映射到同一片空间,对数据存放取出即可
2.共享内存的操作步骤:
1.创建IPC对象名
ftok
2.创建共享内存
shmget
int shmget(key_t key, size_t size, int shmflg);
功能:
创建共享内存
参数:
key:IPC对象名称
size:共享内存的大小
shmflg:
IPC_CREAT 如果IPC对应的共享内存不存在就创建
IPC_EXCL 如果IPC对应的共享内存存在就报错
返回值:
成功返回创建的共享内存ID
失败返回-1
3.映射
shmat
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:
映射共享内存空间
参数:
shmid:共享内存的ID号
shmaddr:
NULL:系统选择合适的地址映射到共享内存空间中
shmaddr:将该地址(必须为4k的整数倍)映射到共享空间中
SHM_RND 将离传入地址最近的能够映射的地址进行映射
shmflg:
默认为0
返回值:
成功返回映射到共享内存空间中的地址
失败返回-1
4.操作共享内存空间
5.解除映射
shmdt
int shmdt(const void *shmaddr);
功能:
解除映射
参数:
shmaddr:共享内存空间地址
返回值:
成功返回0
失败返回-1
6.删除共享内存
shmctl
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:
向共享内存发送命令
参数:
shmid:共享内存ID号
cmd:
IPC_RMID 删除
buf:
NULL
返回值:
成功返回0
失败返回-1
练习:
1.编写两个程序 clientA.c clientB.c
实现clientA.c从终端接收数据放入共享内存中
clientB.c将共享内存空间中的数据打印在终端
2.信号量数组:
有名信号量
1.ftok
2.semget
int semget(key_t key, int nsems, int semflg);
功能:
创建一个信号量数组
参数:
key:IPC对象名字
nsems:信号量的个数
semflg:
IPC_CREAT
IPC_EXCL
返回值:
成功返回信号量的ID号
失败返回-1
3.semctl
int semctl(int semid, int semnum, int cmd, ...);
功能:
向信号量数组发送命令
参数:
semid:信号量的ID号
semnum:信号量的编号
cmd:命令
IPC_RMID
SETVAL 设置信号量的初始值
返回值:
失败返回-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 */ 对信号量的操作(+1, -1)
short sem_flg; /* operation flags */ 信号量的标志(SEM_UNDO)