当我调用fork()时如何共享内存?

时间:2017-04-29 16:09:17

标签: c process fork

上次,我质疑了。

#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 -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 -1

我的代码存在什么问题?

=

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

但是我应该在2天内解决。

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

我找到了&#39; shm *&#39;但是,没有比shm *更容易解决这个问题的方法了吗?

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

谢谢...

2 个答案:

答案 0 :(得分:0)

分叉时,私有内存页面被标记为&#34; copy-on-write&#34;,这样每个程序都可以继续而不受另一个程序的干扰(否则你会遇到堆栈损坏)时间)。

如果要共享内存,则必须明确指定内存。一种方法是通过mmap系统调用(标题:<sys/mman.h>):

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

成功时,返回一个指向内存区域的指针,该内存区域足以容纳10 int s,具有读写权限,与任何文件(MAP_ANONYMOUS)无关,并将与之共享叉子(MAP_SHARED)。你完成后应该用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;
}

答案 1 :(得分:0)

您可以与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);
}