【问题标题】:How can I share the memory when i call fork() ?调用 fork() 时如何共享内存?
【发布时间】:2017-04-29 16:09:16
【问题描述】:

上次,我质疑。

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

int main(){
int arr[10]={0,};
pid_t pid;
int state;
pid = fork();

if(pid == -1) // error
{
printf("can't fork, error\n");
exit(-1);
}

else if (pid == 0) // Child ( producer )
{
printf("\nProducer is created.\n");

printf("array: ");
for(c=0; c<10; c++)
{
    printf("%d ", arr[c]);
    arr[c]=c+1;
}

}

else // Mother ( consumer )
{
pid=wait(&state);
sleep(1);
printf("\nConsumer takes control of array");


printf("\narray:");

for(j=0;j<10;j++) 
{
    printf(" %d", arr[j]);
}


printf("\nConsumer is done.");

printf("\narray: ");
for ( i =0; i<10; i++)
{

    arr[i]=-1;
    printf("%d ", arr[i]);


}
printf("\ndone\n");
exit(0);
}
return 0;}

我要输出

0 0 0 0 0 0 0 0 0 0

1 2 3 4 5 6 7 8 9 10

-1 -1 -1 -1 -1 -1 -1 -1 -1 -1

但是

我的输出是

0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0

-1 -1 -1 -1 -1 -1 -1 -1 -1 -1

我的代码有什么问题?

=

我写了这个问题, 很多人说我应该使用共享内存, 但我从来没有在课堂上听过..

但我应该在 2 天内解决。

获得解决方案的简单方法是什么。

我找到了“shm*”,但是没有比 shm* 更简单的方法来解决这个问题了吗?

如果存在,请教我简单的例子.....

谢谢...

【问题讨论】:

  • 如果只是为了完成它,为什么不直接写入文件并从中读取。或者更好的是,使用管道。
  • 你知道你可以通过网络学习东西,而不必在课堂上听。这是一项有用的学习技能

标签: c process fork


【解决方案1】:

您可以通过 PIPE 进行通信。这是另一种 IPC 机制。

来自 linux 手册: int pipe(int fd[2]) -- 创建一个管道并返回两个文件描述符,fd[0],fd[1]。 fd[0] 用于读取,fd[1] 用于写入。

满足您要求的代码:

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

int main(void)
{
    int     fd[2], nbytes;
    pid_t   pid;
    int arr[10]={0,};
    int readbuffer[10];
    int state, c, i, j;

    pipe(fd);

    if((pid = fork()) == -1)
    {
        printf("can't fork, error\n");
        exit(-1);
    }
    else if(pid == 0)
    {
            /* Child process closes up input side of pipe */
            close(fd[0]);

            /* Send "arr" through the output side of pipe */
            printf("\nProducer is created.\n");

            printf("array: ");
            for(c=0; c<10; c++)
            {
                printf("%d ", arr[c]);
                arr[c]=c+1;
            }

            write(fd[1], arr, (sizeof(int)*10));
            exit(0);
    }
    else
    {
            /* Parent process closes up output side of pipe */
            close(fd[1]);

            pid=wait(&state);
            sleep(1);
            printf("\nConsumer takes control of array");

            /* Read in arr from the pipe */
            nbytes = read(fd[0], arr, (sizeof(int)*10));

            printf("\narray:");

            for(j=0;j<10;j++) 
            {
                printf(" %d", arr[j]);
            }

            printf("\nConsumer is done.");

            printf("\narray: ");
            for ( i =0; i<10; i++)
            {
                arr[i]=-1;
                printf("%d ", arr[i]);
            }
            printf("\ndone\n");
            exit(0);

    }

    return(0);
}

【讨论】:

    【解决方案2】:

    在分叉时,私有内存页面被标记为“写时复制”,这样每个程序都可以继续运行而不会干扰其他程序(否则你很快就会遇到堆栈损坏)。

    如果您希望共享内存,则必须明确指定。一种方法是通过mmap 系统调用(标头:&lt;sys/mman.h&gt;):

    mmap(NULL, 10 * sizeof(int), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
    

    成功时,这将返回一个指向足够大的内存区域的指针,该内存区域可以容纳 10 个ints,具有读写权限,不与任何文件关联 (MAP_ANONYMOUS),并将与分叉共享 (@987654326 @)。完成后,您应该使用munmap 释放内存。

    这意味着您只需将数组更改为指针并在运行时分配内存:

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <stdlib.h>
    #include <sys/mman.h>
    
    int main(void)
    {
        int *arr;
        pid_t pid;
        int state;
        int c, i, j;
    
        arr = mmap(NULL, 10 * sizeof(int), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
        if(arr == MAP_FAILED)
        {
            printf("mmap failed\n");
            exit(-1);
        }
    
        pid = fork();
        if(pid == -1) // error
        {
            printf("can't fork, error\n");
            exit(-1);
        }
    
        else if(pid == 0) // Child ( producer )
        {
            printf("\nProducer is created.\n");
    
            printf("array: ");
            for(c = 0; c < 10; c++)
            {
                printf("%d ", arr[c]);
                arr[c] = c + 1;
            }
        }
    
        else // Mother ( consumer )
        {
            pid = wait(&state);
            sleep(1);
            printf("\nConsumer takes control of array");
    
            printf("\narray:");
            for(j = 0; j < 10; j++)
            {
                printf(" %d", arr[j]);
            }
            printf("\nConsumer is done.");
    
            printf("\narray: ");
            for( i = 0; i < 10; i++)
            {
                arr[i] = -1;
                printf("%d ", arr[i]);
            }
            printf("\ndone\n");
        }
    
        munmap(arr, 10 * sizeof(int));
        return 0;
    }
    

    【讨论】:

    • @MatteoItalia wait 用于实际同步...我刚刚离开 sleep 因为 OP 把它放在那里。
    • 哦,抱歉,我没注意到。我的错。
    猜你喜欢
    • 2010-12-30
    • 2021-12-04
    • 2013-03-06
    • 1970-01-01
    • 2011-02-10
    • 2012-04-26
    • 2011-07-31
    • 1970-01-01
    • 2021-01-19
    相关资源
    最近更新 更多