问题描述:通过创建进程共享的内存,只调用一次fork();子进程进行生成斐波那契数列,并将生成的斐波那契数列放入共享内存段。父进程等待子进程执行完成后执行,将子进程生成在共享内存段的斐波那契数列进行输出。
注:该代码只能在linux环境下运行。
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <fcntl.h>
//< unistd.h > 包含了POSIX操作系统API的标准符号常量、类型和函数原型,例如fork()、pipe()、exec()等等。它定义了常见的系统调用和常量,例如文件描述符和进程ID。
//<sys/mman.h> 包含了内存管理相关的系统调用,例如mmap()、munmap()等等。它提供了内存映射文件和匿名内存映射的功能。
//<sys/wait.h> 包含了与等待子进程相关的函数和类型定义,例如wait()、waitpid()等等。
//<fcntl.h> 包含了对文件描述符的控制相关的函数和类型定义,例如open()、close()等等。它定义了文件访问模式、文件打开标志等等。
#define MAX 50
using namespace std;
//创建一个共享数据段的结构体,包含一个数组,和用于记录数组大小的int
typedef struct {
int fib_sequence[MAX];
int sequence_size;
} shared_data;
int main(void) {
int fd;
shared_data* data;
// 创建共享数据段
fd = shm_open("/myshm", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
//shm_open()函数的第一个参数是共享内存对象的名称/第二个参数是一个标志位/第三个参数是权限位掩码
//函数执行成功后,会返回一个非负整数的文件描述符,可以用于后续对共享内存对象进行读写操作。
//如果shm_open()函数执行失败,则返回值为-1,并且设置相应的错误码。
if (fd == -1) {
perror("shm_open");
exit(EXIT_FAILURE);
}
// Set size of shared memory segment
if (ftruncate(fd, sizeof(shared_data)) == -1) {
perror("ftruncate");
exit(EXIT_FAILURE);
}
// Map shared memory segment into process address space
data = (shared_data*)mmap(NULL, sizeof(shared_data), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
//这是一个使用mmap()函数将共享内存段映射到进程地址空间的语句。
//第四个参数是MAP_SHARED,指定共享内存段将在多个进程之间共享,而不是只在当前进程内使用。
if (data == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
//初始化共享内存的值,初始化共享内存中的斐波那契数列为0
data->sequence_size = 0;
for (int i = 0; i < MAX; i++) {
data->fib_sequence[i] = 0;
}
// Fork a child process
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
else if (pid == 0) { //成功生成子序列、在子进程中生成斐波那契数列
data->sequence_size = MAX;
data->fib_sequence[0] = 0;
data->fib_sequence[1] = 1;
for (int i = 2; i < MAX; i++) {
data->fib_sequence[i] = data->fib_sequence[i - 1] + data->fib_sequence[i - 2];
}
// Exit child process
exit(EXIT_SUCCESS);
}
else {//(pid==1)父进程
// Parent process waits for child to finish
wait(NULL);
// Print fibonacci sequence
cout << "Fibonacci sequence:" << endl;
for (int i = 0; i < data->sequence_size; i++) {
cout << data->fib_sequence[i] << " ";
}
cout << endl;
// 删除共享内存段
if (shm_unlink("/myshm") == -1) {
perror("shm_unlink");
exit(EXIT_FAILURE);
}
// Exit parent process
exit(EXIT_SUCCESS);
}
}
代码运行时需要注意的问题。
很明显不能直接g++,因为库里面不包含shm 库(共享内存调用的函数)
因此在 Linux 系统中,使用 -lrt
选项链接 rt
库。例如:g++ your_code.cpp -o your_program -lrt
这将链接 rt
库并生成可执行文件 your_program
。