1. 概述:
该demo主要实现linux下进程之间的共享内存通信, 相关接口介绍可以参考<<UNIX环境高级编程>>
2. 场景(半双工):
父进程简单地通过共享内存将数据发送给子进程
3. 测试:
/*
demo_process_IPC_shmget.c
进程编程demo(共享内存)
IPC相关的命令: ipcs ipcrm(释放IPC)
查看进程属性: ulimit -a
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/shm.h>
#define SHM_ID 1
#define MAX_BUF 64
struct shm_st
{
bool flag; // 0 : 不可读, 1 : 可读
char buf[MAX_BUF]; // 数据
};
int main(int argc, char **argv){
pid_t pid;
int shmid = -1;
key_t key_shm = SHM_ID;
/*
IPC_CREAT | IPC_EXCL, 如果没有该共享内存, 则创建, 并返回共享内存ID
若已有该共享内存, 则返回-1
*/
shmid = shmget(key_shm, sizeof(struct shm_st), 600|IPC_CREAT|IPC_EXCL);
if (shmid < 0){
/*printf("shmget:%s\n", strerror(errno));*/
perror("shmget:");
return -1;
}
/*
父 -> 子
*/
pid = fork();
if(pid < 0){
perror("fork:");
if (shmctl(shmid, IPC_RMID, 0) < 0){
perror("shmctl:");
}
return -1;
}else if(pid == 0){
printf("child process\n"); /*子进程*/
void * shm = NULL;
struct shm_st * shared = NULL;
/*
shm_addr : 指定共享内存连接到当前进程中的地址位置, 通常为空, 表示让系统来选择共享内存的地址
shm_flg : 一组标志位, 通常为0
*/
shm = shmat(shmid, 0, 0);
if (shm == (void *)-1){
perror("shmat:");
return -1;
}
shared = (struct shm_st *)shm;
while(1){
if(shared->flag == 1){
printf("child process\t shared->buf = %s\n", shared->buf);
break;
}
usleep(1 * 1000);
}
/* 把共享内存从当前进程中分离 */
if (shmdt(shm) < 0){
perror("shmdt:");
}
shm = NULL;
shared = NULL;
}else{
printf("parant process\n"); /*父进程*/
void * shm = NULL;
struct shm_st * shared = NULL;
shm = shmat(shmid, 0, 0);
if (shm == (void *)-1){
perror("shmat:");
return -1;
}
shared = (struct shm_st *)shm;
shared->flag = 0;
memset(shared->buf, 0x0, sizeof(shared->buf));
memcpy(shared->buf, "demo_process_IPC_shmget", sizeof(shared->buf));
printf("parant process\t shared->buf = %s\n", shared->buf);
shared->flag = 1;
if (shmdt(shm) < 0){
perror("shmdt:");
}
shm = NULL;
shared = NULL;
wait(NULL);
/* 删除共享内存段 */
if (shmctl(shmid, IPC_RMID, 0) < 0){
perror("shmctl:");
}
}
return 0;
}
#Makefile
CC := gcc
INCLUDE = -I /home/demo/include/
all:
$(CC) demo_process_IPC_shmget.c $(INCLUDE) -o demo_process_IPC_shmget -Wall -Werror
clean:
rm demo_process_IPC_shmget