这道题是在3.14 的基础上,实现父进程与子进程之间数据的共享。
思路为书中所讲的 《POSIX共享内存》 实例。
采用生产者–消费者模型实现共享内存。生产者创建一个共享内存对象,想共享内存中写入;消费者从共享内存中读出。
生产者进程:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main(int argc, char *argv[])
{
const int SIZE = 4096; //用于指定共享内存 段的大小
const char *name = "COLLATZ";
int shm_fd;
void *ptr; //用于指向内存映射文件的指针
char str[128];
int n = atoi(argv[1]);
/* 创建一个共享内存对象 */
shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);
/* 配置共享内存的大小 */
ftruncate(shm_fd,SIZE);
/* 创建内存映射文件,用来包含共享内存对象。也可以这样理解:在进程的地址空间中映射共享内存段 */
ptr = mmap(0,SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) {
printf("Map failed\n");
exit(-1);
}
/**
* 将Collatz序列写入共享存储区域
*
* 在每次写入后增加ptr的值,移动指针
*/
sprintf(str,"%d, ", n); //将参数存放到str中
sprintf(ptr,"%s",str); //从str中读取数据放入共享存储区域
while (n != 1) { //这一部分用来实现Collatz算法
ptr += strlen(str);
if (n % 2 == 0)
n = n / 2;
else
n = 3 * n + 1;
sprintf(str,"%d, ", n);
sprintf(ptr,"%s",str);
}
return 0;
}
消费者进程:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
int main()
{
const char *name = "COLLATZ";
const int SIZE = 4096;
int shm_fd;
void *ptr;
int i;
/* 创建共享内存对象 */
shm_fd = shm_open(name, O_RDONLY, 0666);
if (shm_fd == -1) {
printf("shared memory failed\n");
exit(-1);
}
/* 在进程的地址空间中映射共享内存段 */
ptr = mmap(0,SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);
if (ptr == MAP_FAILED) { //MAP_FAILED是一个状态,意味着映射失败
printf("Map failed\n");
exit(-1);
}
/* 从共享内存区域中读取数据 */
printf("%s",(char *)ptr);
/* 删除共享内存对象 */
if (shm_unlink(name) == -1) {
printf("Error removing %s\n",name);
exit(-1);
}
return 0;
}