C中的分叉和共享内存
Fork and shared memory in C
这是我的问题:
- 创建进程
- 创建一个char buffer的共享变量
- 每个进程将写入一个 char 值(假设 50 次)即 'A'、'B'、'C' 等到共享内存中并打印出缓冲区大小结束后
- 我需要添加 sleep 语句,以便将 char 值添加到共享值的顺序是这样的
Child -> Grand child 1 -> Grand child 2 -> Great Grand child 1 -> Great Grand child 2
- 最后打印最终缓冲区
所以首先我想创建这样的进程,父进程将有一个子进程。每个子进程都会有孙子进程,每个孙子进程都会有曾孙子,如此处所示。
我正在使用 IF-ELSE 结构来实现这一点,但我需要先创建所有进程,然后再开始工作,不知道如何实现。我不知道代码进程有什么问题,没有向缓冲区或共享值中添加任何内容。我之所以这样说是因为当进程在执行后打印缓冲区大小时,每个进程都是相同的。
代码
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include <sys/wait.h>
#include<sys/ipc.h>
#include<sys/shm.h>
using namespace std;
// Driver Code
int main()
{
// number of chars values the process will write
int child_chrs = 1000;
int grand_child1_chrs = 700;
int grand_child2_chrs = 300;
int great_grand_child1_chrs = 700;
int great_grand_child2_chrs = 300;
int fd[2];
pipe(fd);
int shared_index = 0, n =0;
write(fd[1], &n, sizeof(n));
key_t key = ftok("shmfile",65); // generate unique key
int shmid = shmget(key,1024,0666|IPC_CREAT); // get identifier in shmid
char *stringValue = (char*) shmat(shmid,(void*)0,0); // attach to shared memory
cout << "Parent process has been created." << endl;
cout << "Shared memory creation was successful." << endl;
if (fork() == 0) // Child
{
if(fork() == 0) // Grand Child 1
{
if(fork() == 0) // Great Grand Child 1
{
while(great_grand_child1_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'Y';
great_grand_child1_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
}
cout << "From Great-grandchild1 process - I just finished and the buffer size = " << shared_index << endl;
cout << "From Great-grandchild1 process terminated normally\n";
}
else // Great Grand Child 2
{
while(grand_child1_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'B';
grand_child1_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
}
cout << "From Great-grandchild2 process - I just finished and the buffer size = " << shared_index << endl;
cout << "From Great-grandchild2 process terminated normally\n";
}
}
else // Grand Child 2
{
if(fork() == 0) // Grand Child 1
{
if(fork() == 0) // Grand Child 2
{
while(great_grand_child2_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'Z';
great_grand_child2_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
//cout<<"\nshared index: "<<shared_index;
}
cout << "From Grandchild1 process - I just finished and the buffer size = " << shared_index << endl;
cout << "The Grandchild1 process terminated normally.\n";
}
else // Grand Child 2
{
while(grand_child2_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'C';
grand_child2_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
}
cout << "From Grandchild2 process - I just finished and the buffer size = " << shared_index << endl;
cout << "The Grandchild2 process terminated normally.\n";
}
}
else // Child
{
while(child_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'A';
child_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
}
cout << "From Child process - I just finished and the buffer size = " << shared_index << endl;
cout << "The Child process terminated normally.\n";
}
}
}
else // Parent
{
wait(NULL);
cout<<"\n\nResultant Buffer is:\n\n";
cout << "From Parent process - I am exiting and final buffer size = " << shared_index << endl;
shmdt(stringValue);
cout << "Shared memory has been released.\n";
}
}
输出
From Child process - I just finished and the buffer size = 5
The Child process terminated normally.
Resultant Buffer is:
From Parent process - I am exiting and final buffer size = 0
Shared memory has been released.
From Grandchild2 process - I just finished and the buffer size = 5
The Grandchild2 process terminated normally.
注意:我知道代码是用 C++ 编写的,它需要用 C 编写,当我开始编写此代码时,我发现的示例是用 C++ 编写的,但我不知道会使其成为 C 代码的更改。我可能会犯一些愚蠢的错误,因为我不是一个出色的 C 程序员,我在 Java、Python、Ruby 和 C# 方面经验丰富,但 C 不是我的经验。
请访问https://www.man7.org/linux/man-pages/man2/read.2.html了解read()系统调用的语法。
成功时,它return是它读取的字节数,这里是 4。
例如,
shared_index = read(fd[0], &shared_index, sizeof(int));
将始终return 4 作为它成功读取的字节数。
所以请改变你的逻辑。
这是我的问题:
- 创建进程
- 创建一个char buffer的共享变量
- 每个进程将写入一个 char 值(假设 50 次)即 'A'、'B'、'C' 等到共享内存中并打印出缓冲区大小结束后
- 我需要添加 sleep 语句,以便将 char 值添加到共享值的顺序是这样的
Child -> Grand child 1 -> Grand child 2 -> Great Grand child 1 -> Great Grand child 2
- 最后打印最终缓冲区
所以首先我想创建这样的进程,父进程将有一个子进程。每个子进程都会有孙子进程,每个孙子进程都会有曾孙子,如此处所示。
我正在使用 IF-ELSE 结构来实现这一点,但我需要先创建所有进程,然后再开始工作,不知道如何实现。我不知道代码进程有什么问题,没有向缓冲区或共享值中添加任何内容。我之所以这样说是因为当进程在执行后打印缓冲区大小时,每个进程都是相同的。
代码
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include <sys/wait.h>
#include<sys/ipc.h>
#include<sys/shm.h>
using namespace std;
// Driver Code
int main()
{
// number of chars values the process will write
int child_chrs = 1000;
int grand_child1_chrs = 700;
int grand_child2_chrs = 300;
int great_grand_child1_chrs = 700;
int great_grand_child2_chrs = 300;
int fd[2];
pipe(fd);
int shared_index = 0, n =0;
write(fd[1], &n, sizeof(n));
key_t key = ftok("shmfile",65); // generate unique key
int shmid = shmget(key,1024,0666|IPC_CREAT); // get identifier in shmid
char *stringValue = (char*) shmat(shmid,(void*)0,0); // attach to shared memory
cout << "Parent process has been created." << endl;
cout << "Shared memory creation was successful." << endl;
if (fork() == 0) // Child
{
if(fork() == 0) // Grand Child 1
{
if(fork() == 0) // Great Grand Child 1
{
while(great_grand_child1_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'Y';
great_grand_child1_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
}
cout << "From Great-grandchild1 process - I just finished and the buffer size = " << shared_index << endl;
cout << "From Great-grandchild1 process terminated normally\n";
}
else // Great Grand Child 2
{
while(grand_child1_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'B';
grand_child1_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
}
cout << "From Great-grandchild2 process - I just finished and the buffer size = " << shared_index << endl;
cout << "From Great-grandchild2 process terminated normally\n";
}
}
else // Grand Child 2
{
if(fork() == 0) // Grand Child 1
{
if(fork() == 0) // Grand Child 2
{
while(great_grand_child2_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'Z';
great_grand_child2_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
//cout<<"\nshared index: "<<shared_index;
}
cout << "From Grandchild1 process - I just finished and the buffer size = " << shared_index << endl;
cout << "The Grandchild1 process terminated normally.\n";
}
else // Grand Child 2
{
while(grand_child2_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'C';
grand_child2_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
}
cout << "From Grandchild2 process - I just finished and the buffer size = " << shared_index << endl;
cout << "The Grandchild2 process terminated normally.\n";
}
}
else // Child
{
while(child_chrs!=0)
{
shared_index = read(fd[0], &shared_index, sizeof(int));
*(stringValue+shared_index) = 'A';
child_chrs--;
shared_index++;
write(fd[1], &shared_index, sizeof(int));
}
cout << "From Child process - I just finished and the buffer size = " << shared_index << endl;
cout << "The Child process terminated normally.\n";
}
}
}
else // Parent
{
wait(NULL);
cout<<"\n\nResultant Buffer is:\n\n";
cout << "From Parent process - I am exiting and final buffer size = " << shared_index << endl;
shmdt(stringValue);
cout << "Shared memory has been released.\n";
}
}
输出
From Child process - I just finished and the buffer size = 5
The Child process terminated normally.
Resultant Buffer is:
From Parent process - I am exiting and final buffer size = 0
Shared memory has been released.
From Grandchild2 process - I just finished and the buffer size = 5
The Grandchild2 process terminated normally.
注意:我知道代码是用 C++ 编写的,它需要用 C 编写,当我开始编写此代码时,我发现的示例是用 C++ 编写的,但我不知道会使其成为 C 代码的更改。我可能会犯一些愚蠢的错误,因为我不是一个出色的 C 程序员,我在 Java、Python、Ruby 和 C# 方面经验丰富,但 C 不是我的经验。
请访问https://www.man7.org/linux/man-pages/man2/read.2.html了解read()系统调用的语法。
成功时,它return是它读取的字节数,这里是 4。
例如,
shared_index = read(fd[0], &shared_index, sizeof(int));
将始终return 4 作为它成功读取的字节数。
所以请改变你的逻辑。