使用fork()函数使子进程和父进程共享内存

时间:2012-03-06 23:14:40

标签: c

我正试图让{child}进程创建一个fibonnaci序列并将其存储在fork()作为struc的{​​{1}}场景中。我需要使用赋值中的确切结构,但是我从来没有像这样使用它,所以我假设我在这段代码中的错误与那个有关...

shared_data

我想我正在使用这个错误,但是什么是正确的方法?如果结构是这样的,它将起作用:

26: error: expected identifier (before . token)
39: error: expected identifier (before . token)
44: error: expected expression before shared_data
45: error: expected expression before shared_data

然后我可以使用struct cards{ int a; int b; int c; } cards={0,0,0}; 依此类推......这是我第一次使用这种共享内存结构,同时研究和查看堆栈溢出时,人们会问这些问题是相似的,但他们只是让我更加困惑。做我在下面做的事情的正确方法是什么?

cards.a=3;

4 个答案:

答案 0 :(得分:2)

看起来你在这行代码中有一个拼写错误:

for (j=0; j<=shared+data.sequence_size; j++)

shared+data应为shared_data

答案 1 :(得分:2)

为了在父进程和子进程之间严格共享内存,请不要理会System V共享内存段(shmget,shmat,...)。

使用mmap制作MAP_ANONYMOUS地图,标记为MAP_SHARED。 fork时,该映射不会在父项和子项之间复制,而是共享。

这样做的好处是:1)API简单:只需要​​调用一个函数,获取指针,然后就完成了。 2)自动清理:当两个进程都消失时,内存就会消失。不需要系统管理员进入并执行“ipcrm”来收集垃圾共享内存段。

答案 2 :(得分:1)

fork()创建一个子进程,其中包含父进程内存的精确副本。所以孩子有新的记忆,而不是共享记忆。每个进程都有自己的内存。

您可以通过一个简单的程序来观察:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 

char buffer[128] = "I am the parent.";

int main(int argc, char *argv[]) {
    pid_t pid = fork();

    if (0 == pid) { 
        strcpy(buffer, "I am the child.");
    } else { /* parent process */
        waitpid(pid,0,0); 
        printf("%s", buffer);
    }
    return 0;
}

结果是“我是父母。”如果内存已共享,您可能希望缓冲区被子进程覆盖。那个发生了,但是在一个单独的进程空间中,当孩子死亡时它就会消失。

答案 3 :(得分:1)

您正在使用shared_data作为变量,但是您将其声明为数据类型。

typedef struct{
    long fib_sequence[MAX_SEQUENCE];
    int sequence_size;
} shared_data;

您应将其更改为:

struct{
    long fib_sequence[MAX_SEQUENCE];
    int sequence_size;
} shared_data;

或者,您可以使用datatpye创建一个全局变量:

typedef struct{
    long fib_sequence[MAX_SEQUENCE];
    int sequence_size;
} shared_data;
shared_data sequence;

int fibonacci(int n)
{
  int first = 0;
  int second = 1;
  int total, i;
  for (i=0;i<=n;i++)
  {
    printf("%d\n", first);
    sequence.fib_sequence[i] = first;
    total = first + second;
    first = second;
    second = total;
  }
  return 0;
}
int main(int argc, char *argv[])
{
    int j;
    /*Spawn a child to run the program.*/
    pid_t pid=fork();
    if (pid==0) { /* child process */
        sequence.sequence_size = argc;
        fibonacci(argc);
    }
    else { /* pid!=0; parent process */
        waitpid(pid,0,0); /* wait for child to exit */
        for (j=0; j<=sequence.sequence_size; j++)
            printf("%d\n",sequence.fib_sequence[j]);
    }
    return 0;
}

作为旁注,上述内容并未解决您对argc的错误使用问题。 argc只是向您的程序传递了多少参数的计数。您可能希望将其中一个参数转换为int:

shared_data.sequence_size = (atol(argc) > 10) ? 10 : atol(argc);
fibonacci(shared_data.sequence_size);

希望这有帮助。