общая память не обновляется - PullRequest
1 голос
/ 03 октября 2019

Итак, я пытался узнать немного больше о разделяемой памяти. Я создаю общую структуру памяти в своем мастере и разрываю детей. Затем каждый ребенок создает новый процесс, используя execv. Когда я пытаюсь изменить значение разделяемой памяти из нового процесса, родитель не видит этого изменения. Также я ожидал, что родитель чередует выполнение с дочерним элементом. Например,

Child 1 exec 
parent 
child 2 exec 
parent 
child 3 exec
parent 

Но вместо этого я получаю

child 1 exec 
child 2 exec 
child 3 exec 
parent
parent
parent

, это мой код

simulate.c

# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <time.h>
# include <stdlib.h>
# include <dirent.h>
# include <stdio.h>
# include <string.h>
# include <getopt.h>
# include <stdbool.h>
# include <ctype.h>
# include <sys/wait.h>
# include <signal.h>
# include <sys/mman.h>
# include <sys/time.h>
# include <stdint.h>
# include <fcntl.h>
# include <sys/shm.h>
struct sharedregion{
    volatile int seconds;
    volatile int sharedmsg;
};
struct sharedregion *mystruct;
void spawnchild()
{
    int fd = shm_open("sharedmemory", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IRWXG | S_IRWXU);
    if (fd == -1)
        perror("Error in opening");
    if (ftruncate(fd, sizeof(struct sharedregion)) == -1)
        perror("Unable to truncate");
    mystruct = mmap(NULL, sizeof(struct sharedregion),PROT_READ | PROT_WRITE, MAP_SHARED| MAP_ANONYMOUS, fd, 0);
    if (mystruct == MAP_FAILED)
        perror("mapping failed");
    mystruct->seconds=0;
    mystruct->sharedmsg=0;
    int i;
    for(i=0;i<4;i++)
    {
        pid_t pID = fork();

        if (pID == 0)
        {
            static char *args[]={"./child",NULL};

            execv(args[0], args);
            perror("failed to execv");
            exit(EXIT_FAILURE);

        }
        else if (pID < 0)            // failed to fork
        {
            perror(" Failed to fork:");
            exit(EXIT_FAILURE);
        }
        else if(pID>0)
        {

            printf("\nfrom parent= %d",mystruct->sharedmsg);
            mystruct->seconds=mystruct->seconds+1;
            if(mystruct->seconds==1000000000)
            {
                mystruct->seconds=1;
            }
        }
    }
}
int main(int argc, char **argv)
{
    spawnchild();
}

child.c

# include <unistd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <time.h>
# include <stdlib.h>
# include <dirent.h>
# include <stdio.h>
# include <string.h>
# include <getopt.h>
# include <stdbool.h>
# include <ctype.h>
# include <sys/wait.h>
# include <signal.h>
# include <sys/mman.h>
# include <sys/time.h>
# include <stdint.h>
# include <fcntl.h>
# include <sys/shm.h>
struct sharedregion{
    volatile int seconds;
        volatile int sharedmsg;
};
struct sharedregion *mystruct;

int main(int argc, char **argv)
{
    int memFd = shm_open("sharedmemory", O_RDWR, S_IRUSR | S_IWUSR | S_IRWXG | S_IRWXU);
    if (memFd == -1)
    {
        perror("Can't open file");
        return 1;
    }

    mystruct = mmap(NULL, sizeof (struct sharedregion), PROT_READ | PROT_WRITE, MAP_SHARED| MAP_ANONYMOUS, memFd, 0);

    printf("\nhello from exec");
    mystruct->sharedmsg=8;
    printf("buffer %d",mystruct->sharedmsg);

    return 0;
}

Мой вывод

hello from execbuffer 8
hello from execbuffer 8
hello from execbuffer 8
hello from execbuffer 8
hello from execbuffer 8
from parent= 0
from parent= 0
from parent= 0
from parent= 0
from parent= 0

1 Ответ

2 голосов
/ 03 октября 2019

Снимите флаг MAP_ANONYMOUS

согласно инструкции:

MAP_ANONYMOUS [...] Аргумент fd игнорируется;

, таким образом, онигнорирует вашу общую память

...