0
    class test_class
    {
       public:
       std::string str;
       int ival;
    };

    int main()
    {
        int shmkey = 3450;
        int shmid;

        if((shmid = shmget(shmkey, sizeof(test_class*), IPC_CREAT | 0666)) < 0)
        {
            perror("shmget");
            exit(1);
        }

        test_class **test_obj;
        if((test_obj = (test_class**) shmat(shmid, NULL, 0)) == (test_class**) -1)
        {
            perror("shmat");
            exit(1);
        }

        test_class* new_obj = new test_class();
        *test_obj = new_obj;

        (*test_obj)->str = "parent process string";
        (*test_obj)->ival = 9;

        pid_t pid = fork();

        if(pid == 0)
        {
            int shmkey = 3450;
            int shmid;

            if((shmid = shmget(shmkey, sizeof(test_class*), 0666)) < 0)
            {
                perror("shmget");
               exit(1);
            }

            test_class **test_obj;
            if((test_obj = (test_class**) shmat(shmid, NULL, 0)) == (test_class**) -1)
            {
                perror("shmat");
                exit(1);
            }

            (*test_obj)->str = "child process string";
            (*test_obj)->ival = 10;

            exit(EXIT_SUCCESS);
        }

        sleep(3);
        std::cout << (*test_obj)->str << std::endl;
        std::cout << (*test_obj)->ival << std::endl;

        shmctl(shmid, IPC_RMID, 0);

        return 0;
    }


This code output is :-
child process string
9

在这个程序中,我正在更新子进程中的共享内存对象(在堆内存中)并在父进程中打印更新的值。正如我们从输出中看到的,它正确地更新了字符串而不是 int。因为它在堆内存中,所以它不应该更新。字符串在这里如何更新?

对此有什么帮助吗?

谢谢,高拉夫

4

1 回答 1

2

您的代码有几个问题:

1)父进程不会等待子进程完成对对象的修改,因此无法预测它会输出什么。在输出值之前放入wait(NULL)父进程;

2)子进程改变了一个std::string,实际上改变了string对象内部的一些指针,但是子进程和父进程不同的堆和不同的地址空间,所以这是非常危险的。您应该将数组存储char在共享内存中;

3)由于共享内存已经在父进程中获得并复制在子进程中,因此无需在子进程中执行shmget& ;shmatfork

4)您应该指定 as 的字段,test_class以便volatile编译器不会优化读取它们的值。

于 2013-06-10T20:58:17.233 回答