【问题标题】:Fork and shared memory in CC中的fork和共享内存
【发布时间】:2021-01-19 22:47:24
【问题描述】:

这是我的问题:

  • 创建进程
  • 制作一个char缓冲区的共享变量
  • 每个进程都会将一个 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 不是我有经验的。

【问题讨论】:

  • 这是“你能把这个 C++ 代码转换成 C 吗?”
  • 不,我不是要求转换,我会自己做,但由于我的代码没有按预期工作,我需要先修复它
  • shared_index = read(fd[0], &amp;shared_index, sizeof(int)); 似乎是错误的。这将使用read(将是sizeof(int)、0 或-1)的返回码覆盖您从管道中读取的数据。
  • 另请注意,对于任何指针或数组p 和索引i,表达式*(p + i) 完全 等于p[i]。后一种语法更易于阅读和编写。所以请不要写例如*(stringValue+shared_index),而是stringValue[shared_index]。
  • 旁注:家谱是继承的不良类比。派生类is-a 基类。所以在家谱中,孩子是父母,也是祖父母,这是没有意义的。请参阅 What is an example of the Liskov Substitution Principle? 了解一个方便的工具,以帮助了解继承层次结构何时有意义

标签: c++ fork shared-memory


【解决方案1】:

请访问https://www.man7.org/linux/man-pages/man2/read.2.html了解read()系统调用的语法。

成功时,它返回读取的字节数,此处为 4。

例如,

shared_index = read(fd[0], &shared_index, sizeof(int));

将始终返回 4 作为它成功读取的字节数。

所以请在那里改变你的逻辑。

【讨论】:

    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 2012-04-26
    • 2010-12-30
    • 2011-07-31
    • 1970-01-01
    • 2021-12-04
    • 2013-03-06
    • 1970-01-01
    相关资源
    最近更新 更多