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

C 调用fork()时如何共享内存?,c,process,fork,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 i

上次,我问

#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;}
#包括
#包括
#包括
#包括
int main(){
int arr[10]={0,};
pid_t pid;
int状态;
pid=fork();
如果(pid=-1)//错误
{
printf(“无法分叉,错误\n”);
出口(-1);
}
else if(pid==0)//子级(生产者)
{
printf(“\n已创建生产者。\n”);
printf(“数组:”);

对于(c=0;c分叉时,专用内存页被标记为“写入时复制”,这样每个程序都可以在不受其他程序干扰的情况下继续运行(否则很快就会遇到堆栈损坏)

如果希望共享内存,则必须明确指定。其中一种方法是通过
mmap
syscall(header:
):

成功后,将返回一个指向足够容纳10个
int
s的内存区域的指针,该内存区域具有读写权限,与任何文件(
MAP\u ANONYMOUS
)都没有关联,并将与forks(
MAP\u 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;
}
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
int*arr;
pid_t pid;
int状态;
int c,i,j;
arr=mmap(NULL,10*sizeof(int),PROT_READ | PROT_WRITE,MAP_ANONYMOUS | MAP_SHARED,-1,0);
如果(arr==MAP_失败)
{
printf(“mmap失败\n”);
出口(-1);
}
pid=fork();
如果(pid=-1)//错误
{
printf(“无法分叉,错误\n”);
出口(-1);
}
else if(pid==0)//子级(生产者)
{
printf(“\n已创建生产者。\n”);
printf(“数组:”);
对于(c=0;c<10;c++)
{
printf(“%d”,arr[c]);
arr[c]=c+1;
}
}
其他//母亲(消费者)
{
pid=等待(&状态);
睡眠(1);
printf(“\n消费者控制数组”);
printf(“\narray:”);
对于(j=0;j<10;j++)
{
printf(“%d”,arr[j]);
}
printf(“\n消费完成。”);
printf(“\narray:”);
对于(i=0;i<10;i++)
{
arr[i]=-1;
printf(“%d”,arr[i]);
}
printf(“\ndone\n”);
}
munmap(arr,10*sizeof(int));
返回0;
}

您可以与管道通信。这是另一种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);
}
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
int-fd[2],n字节;
pid_t pid;
int arr[10]={0,};
int readbuffer[10];
int状态,c,i,j;
管道(fd);
如果((pid=fork())=-1)
{
printf(“无法分叉,错误\n”);
出口(-1);
}
否则如果(pid==0)
{
/*子进程关闭管道的输入端*/
关闭(fd[0]);
/*通过管道的输出侧发送“arr”*/
printf(“\n已创建生产者。\n”);
printf(“数组:”);

对于(c=0;cIf这只是为了完成它,为什么你不直接写一个文件并从中读取。或者更好的是,使用管道。你知道你可以通过网络学习东西,而不必在课堂上听到。这是一项非常有用的技能learn@MatteoItalia
等待
用于实际同步…我刚刚离开了
睡眠
be因为OP把它放在那里了抱歉我没注意到我的错。
#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);
}