前言:历程间的通信方式包罗
IPC:
1、管道
pipe 无名管道
fifo 有名管道
2、信号 signal
3、消息队列 System V消息队列 / POSIX消息队列
4、共享内存 System V共享内存 / POSIX共享内存 <-----------
5、信号量 System V信号量 / POSIX信号量
6、socket套接字
1、共享内存
共享内存是历程间通信的一种方式,多个历程共享一段内存空间 “共享内存”
由于多个历程共享同一个内存,你往这个内存中写入数据,现实上就是往我的内存中写入数据
随内核的持续性
实现方式:
在内核中开辟了一块空间,其他历程通过 “内存映射” 的方式
获取到这个共享内存的首地点
历程p1可以映射这段内存,其他历程p2也可以映射这段内存
p1往这段内存中写入数据,现实上就是往p2中写入数据
2、System V 共享内存的相关接口函数
System V IPC (msg/shm/sem) 操作流程:
(1)获取键值key
(2)创建或打开一个IPC对象,获取IPC对象的id
(3)操作:发送/接收
(4)其他控制操作: 删除/获取、设置属性/...
1)获取键值key - ftok函数
2)创建大概打开一个System V共享内存 shmget
NAME
shmget - allocates a System V shared memory segment
SYNOPSIS
#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);
功能:获取一块共享内存
参数:
key: 共享内存的键值
size: 共享内存的巨细 ,单位 字节
当现实操作是 创建一个新的共享内存时,必须指定一个不为0的size值
当现实操作是 打开一个共享内存时,那么size==0
shmflg: 标志
(1)创建标志
IPC_CREAT | 权限
例子:
IPC_CREAT | 0666
注意:
如果创建失败的缘故原由 是因为已经存在了
且 创建的标志为 IPC_CREAT | IPC_EXCL 一起使用
此时 errno == EEXIST
(2)打开标志
0
返回值:
成功,返回共享内存的id
失败,返回-1,并设置errno
3)共享内存的映射和解映射
NAME
shmat, shmdt - System V shared memory operations
SYNOPSIS
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:用来映射一个System V共享内存到历程的地点空间
参数:
shmid: 共享内存的id
shmaddr:指定映射到历程地点空间的哪个位置上
一般为 NULL 让它自行分配
shmflg:映射标志
SHM_RDONLY 只读
0 可读可写
返回值:
成功,返回映射地区的首地点
失败,返回(void *) -1,同时errno被设置
int shmdt(const void *shmaddr);
功能:解除映射
参数:
shmaddr: 映射地区的首地点
返回值:
成功,返回0
失败,返回-1,并设置errno
- 创建一个共享内存,实现父子进程的通信
- 子进程 --》 写入数据
- 父进程 --》 读取数据,并打印
- #define PATHNAME "/home/china/"
- int main()
- {
- //1.获取键值key
- key_t key = ftok( PATHNAME, 5 );
- if( key == -1 )
- {
- perror("ftok error ");
- return -1;
- }
- printf("key = 0x%x\n", key );
- //2.创建或打开一个System V共享内存
- int shm_id = shmget( key, 4096, IPC_CREAT | IPC_EXCL | 0666 );
- if( shm_id == -1 )
- {
- if( errno == EEXIST ) //已经存在 就直接打开
- {
- shm_id = shmget( key, 0, 0 );
- }
- else
- {
- perror("shmget error ");
- return -1;
- }
- }
- printf("shm_id = %d\n", shm_id );
- //3.映射
- char * p = shmat( shm_id, NULL, 0 );
- if( p == NULL )
- {
- perror("shmat error ");
- return -1;
- }
- //4.创建一个子进程
- pid_t pid = fork();
- if( pid > 0 ) //父进程
- {
- //等待子进程退出
- wait( NULL );
- //读取数据,打印
- printf("father : %s\n", p );
- //5.解除映射
- shmdt( p );
- }
- else if( pid == 0 ) //子进程
- {
- //写入数据
- printf("child : ");
- fgets( p, 128, stdin );
- }
- else
- {
- perror("fork error ");
- shmdt( p );
- return -1;
- }
- }
复制代码
4)共享内存的控制操作shmctl
NAME
shmctl - System V shared memory control
SYNOPSIS
#include <sys/ipc.h>
#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:对共享内存的其他控制操作
参数:
shmid: 共享内存id
cmd: 命令号
IPC_RMID 删除
IPC_STAT 获取属性
IPC_SET 设置属性
...
buf: 结构体指针 , 具体根据cmd的差别,有差别寄义
如果 cmd == IPC_RMID ,那么就填 NULL
返回值:
成功,返回0
失败,返回-1,同时errno被设置
- struct shmid_ds
- {
- struct ipc_perm shm_perm; /* Ownership and permissions */
- size_t shm_segsz; /* Size of segment (bytes) */
- time_t shm_atime; /* Last attach time */
- time_t shm_dtime; /* Last detach time */
- time_t shm_ctime; /* Last change time */
- pid_t shm_cpid; /* PID of creator */
- pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
- shmatt_t shm_nattch; /* No. of current attaches */
- ...
- };
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |