c++ - shmget shmat 无法正常工作

标签 c++ linux memory shared-memory

<分区>

    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。由于它在堆内存中,因此不应更新。此处的字符串如何更新?

有什么帮助吗?

谢谢, 高拉夫

最佳答案

您的代码有几个问题:

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

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

3) 不需要执行shmget & shmat在子进程中,因为共享内存已经在父进程中获得并在 fork 中复制;

4) 你应该指定 test_class 的字段作为volatile这样编译器就不会优化读取它们的值。

关于c++ - shmget shmat 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17032549/

相关文章:

c++ - AMP 的非矩形数据包装器?

C++模板函数重载规则

linux - 在一个非常大的文件的第一行进行多次替换

linux - 找出一个进程在 linux 中使用了多少额外的物理内存

c++ - 等待线程直到条件发生

c++ - Solaris 9 上的 printf + uint64?

node.js - 无法启动 chrome [FATAL :zygote_host_impl_linux. cc(116)] 没有可用的沙箱

linux - 适用于 Linux 的 Xscale 编译器? (还有 Xscale 编译标志问题)

c - 在内存中查找进程页面(linux-kernel)

javascript - 对象引用会占用额外的内存吗?