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。因为它在堆内存中,所以不应该更新。字符串是如何在这里更新的?
在这方面有什么帮助吗?
谢谢,Gaurav
发布于 2013-06-10 20:58:17
您的代码有几个问题:
1)父进程不会等待子进程完成对象的修改,因此它输出的内容是不可预测的。在输出值之前将wait(NULL)放入父进程;
2)子进程改变了std::string,实际上它改变了string对象中的一些指针,但是子进程和父进程有不同的堆和不同的地址空间,所以这是非常危险的。您应该将char数组存储在共享内存中;
3)不需要在子进程中执行shmget和shmat,因为共享内存已经在父进程中获得,并且在fork中复制;
4)应该将test_class的字段指定为volatile,这样编译器就不会优化读取它们的值。
https://stackoverflow.com/questions/17032549
复制相似问题