system-v 共享内存
作用:高效率传输大量数据
共享内存用法
- 定义一个唯一的key//ftok()
- 构造一个共享内存对象//shmget()
- 共享内存映射//shmat()
- 解除共享内存映射//shmdt()
- 删除共享内存//shmctl() RMID
shmget() :获取共享内存对象的ID
int shmget(key_t key, size_t size, int shmflg);
参数说明:
- key:标识共享内存的键值
- size:要创建共享内存的大小,所有的内存分配操作都是以页为单位的,所以即使只申请只有一个字节的内存,内存也会分配整整一页。
- shmflg:
- IPC_CREAT:共享内存不存在则创建。
- mode:共享内存的权限
返回值:
成功:共享内存ID
失败:-1
shmat() 映射函数:映射共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);
参数:
- shmid:共享内存id
- shmaddr:映射地址,NULL为自动分配
- shmflg:
- SHM_RDONLY:只读方式映射
- 0:可读可写
返回值:
成功:共享内存首地址
失败:-1
shmdt函数:解除共享内存映射
int shmdt(const void *shmaddr);
参数:
- shaddr:映射地址
返回值:
成功:0
失败:-1
shmctl函数:获取或设置共享内存相关属性
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
- shmid:共享内存id
- cmd:
- IPC_STAT:获取共享内存的属性信息
- IPC_SET:设置共享内存的属性
- IPC_RMID:删除共享内存
- buf:用于设置或获取属性信息的数组,IPC_RMID 为:NULL
返回值:
成功:0
失败:-1
main.c
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "sem.h"
#define DELAY_TIME 1 /* 为了突出演示效果,等待几秒钟, */
int main(void)
{
pid_t result;
int sem_id;
int shm_id;
char *addr;
char buf[1024] = "hello world";
sem_id = semget((key_t)666, 1, 0666 | IPC_CREAT); /* 创建一个信号量*/
shm_id = shmget((key_t)7777,1024,0666 | IPC_CREAT);
init_sem(sem_id, 0);
/*调用 fork()函数*/
result = fork();
if(result == -1)
{
perror("Fork\n");
}
else if (result == 0) /*返回值为 0 代表子进程*/
{
printf("Child process will wait for some seconds...\n");
sleep(DELAY_TIME);
addr = (char*)shmat(shm_id,NULL,0);
if(addr == (void*)-1)
{
printf("shmat child error\r\n");
exit(-1);
}
while(1)
{
sleep(DELAY_TIME);
printf("enter data into shared memory:");
memset(buf,0,1024);
if(fgets(buf,10,stdin) == NULL)
{
printf("fgets error\r\n");
exit(-1);
}
memcpy(addr,buf,strlen(buf));
//到支路进行v+操作,也叫信号量释放,这就保证了子进程执行在父进程前面,也就是同步。
sem_v(sem_id);
}
exit(0);
}
else /*返回值大于 0 代表父进程*/
{
while(1)
{
sem_p(sem_id);
printf("get sem\r\n");
//信号为o不能进行p-操作,代码执行到这会阻塞,直到子进程释放信号量。
addr = shmat(shm_id,NULL,0);
if(addr == (void*)-1)
{
printf("shmat parent error\r\n");
exit(-1);
}
printf("shared memory string:%s",addr);
}
shmdt(addr);
shmctl(shm_id,IPC_RMID,NULL);
sem_v(sem_id);
del_sem(sem_id);
exit(0);
}
return 0;
}
其他文件 sem.h sem.c跟system-V 信号量中的文件一样。
该文详细介绍了System-V接口下的共享内存机制,包括shmget()、shmat()、shmdt()和shmctl()等关键函数的使用,并结合信号量实现进程间的同步。在示例代码中,展示了如何创建共享内存、映射及解除映射,并通过信号量控制对共享内存的访问,确保数据的安全传输。

222

被折叠的 条评论
为什么被折叠?



