Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ shmget shmat工作不正常 类测试\u类 { 公众: std::字符串str; 国际竞争力; }; int main() { int-shmkey=3450; int shmid; 如果((shmid=shmget(shmkey,sizeof(test_class*),IPC|u CREAT | 0666))str=“父进程字符串”; (*测试对象)->IVA=9; pid_t pid=fork(); 如果(pid==0) { int-shmkey=3450; int shmid; 如果((shmid=shmget(shmkey,sizeof(test_class*),0666))str=“子进程字符串”; (*测试对象)->IVA=10; 退出(退出成功); } 睡眠(3); std::cout str_C++_Linux_Memory_Shared Memory - Fatal编程技术网

C++ shmget shmat工作不正常 类测试\u类 { 公众: std::字符串str; 国际竞争力; }; int main() { int-shmkey=3450; int shmid; 如果((shmid=shmget(shmkey,sizeof(test_class*),IPC|u CREAT | 0666))str=“父进程字符串”; (*测试对象)->IVA=9; pid_t pid=fork(); 如果(pid==0) { int-shmkey=3450; int shmid; 如果((shmid=shmget(shmkey,sizeof(test_class*),0666))str=“子进程字符串”; (*测试对象)->IVA=10; 退出(退出成功); } 睡眠(3); std::cout str

C++ shmget shmat工作不正常 类测试\u类 { 公众: std::字符串str; 国际竞争力; }; int main() { int-shmkey=3450; int shmid; 如果((shmid=shmget(shmkey,sizeof(test_class*),IPC|u CREAT | 0666))str=“父进程字符串”; (*测试对象)->IVA=9; pid_t pid=fork(); 如果(pid==0) { int-shmkey=3450; int shmid; 如果((shmid=shmget(shmkey,sizeof(test_class*),0666))str=“子进程字符串”; (*测试对象)->IVA=10; 退出(退出成功); } 睡眠(3); std::cout str,c++,linux,memory,shared-memory,C++,Linux,Memory,Shared Memory,您的代码有几个问题: 1) 父进程不等待子进程完成对对象的修改,因此无法预测它将输出什么 2) 子进程更改std::string,实际上它更改string对象内的一些指针,但是子进程和父进程有不同的堆和不同的地址空间,因此这是非常危险的。您应该将char数组存储在共享内存中 3) 无需在子进程中执行shmget&shmat,因为共享内存已在父进程中获得,并在fork中复制 4) 您应该将test\u类的字段指定为volatile,这样编译器就不会优化读取它们的值。5)您正在使用*test\u o

您的代码有几个问题:

1) 父进程不等待子进程完成对对象的修改,因此无法预测它将输出什么

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

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


4) 您应该将
test\u类的字段指定为
volatile
,这样编译器就不会优化读取它们的值。

5)您正在使用
*test\u obj=new test\u class()在共享内存块中存储指向非共享内存的指针;
。这将在示例程序中起作用,但这只是因为整个地址空间有效地复制到位于
fork()的子进程中
。是的,谢谢,我忽略了这一点-我以为他在那里存储了一个对象,而不是指针。如果我在存储对象,我认为不会出现这个问题。无论如何,我的重点是,字符串如何在子进程中更新,因为它也在堆内存中?字符串在父进程中不会更新。我刚刚编译了您的代码,并且打印出来d应该是“父字符串”。也许你没有向我们展示真正的代码?谢谢!你是对的,这不是真正的代码。我知道了,这是因为我在真正的代码中犯了一个错误。字符串也没有更新。
    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