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
您的代码有几个问题: 1) 父进程不等待子进程完成对对象的修改,因此无法预测它将输出什么 2) 子进程更改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
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