进程之间不共享共享内存

时间:2010-10-09 01:02:57

标签: c++ network-programming fork shared-memory

我正在编写一个服务器程序,它从客户端接收消息并向所有以前的客户端发送广播消息。我需要在进程之间创建共享内存,但似乎共享内存不起作用。

这是我的代码:

 int shmid2; key_t key2; void* shm2;
 string name_list;
 key2=ftok("tmp",'d');
 //create
 if ((shmid2 = shmget ( key2, sizeof(char)*1000, IPC_CREAT | 0666)) < 0) {
         perror("shmget2");
         exit(1);}
 //attach
 shm2 = shmat(shmid2, (void *)0, 0) ;
 name_list= (char*) shm2;
 if ( shm2 == (char *) -1) {
        perror("shmat2");
        exit(1);}
 ... do other things...
  switch (pid=fork()){
  case -1:
  { perror("ERROR on fork");
  break;}
  case 0://children
  { 
  ...modify name_list by getting message and append message to name_list..
  name_list.append(message);
  break;}
  default://parent
  close(connection);
  }

当我在子进程中修改name_list时,似乎其他进程看不到此修改。 谁能提出任何建议?谢谢!

更新:我尝试按建议更改为此,但仍然无效。

name_list = (char*) shmat(shmid2, (void *)0, 0) ;

任何人都可以帮我这个吗?非常感谢!

2 个答案:

答案 0 :(得分:1)

std::string对象name_list分配给从共享内存中获取的指针时:

string name_list;
// ...
shm2 = shmat(shmid2, (void *)0, 0) ;
name_list= (char*) shm2;
// ...
name_list.append(message);

你正在调用字符串的赋值运算符,指定的指针复制到新内存中。当您的代码操作name_list时,它正在操纵副本,保持共享内存不受影响。

看起来你正试图从一个进程写入共享内存,并在另一个进程中读取它,这不是一个需要解决的小问题。弄清楚哪个进程可以读取和写入哪些内存是棘手的,就像维护缓存一致性一样。查找生产者 - 消费者循环缓冲区(在Google上或此处在Stack Overflow上),以获得此问题的一些标准解决方案。

要回答原始问题,一旦在本地内存中操作了字符串,就需要将其放回共享内存中。这将在紧要关头:

if(name_list.size() <= 1000) {
    memcpy(shm2, name_list.data(), name_list.size());
} else {
    // error: name list overflowed shared memory
}

你也可以使用指针shm2直接操作共享内存,直接使用C指针,注意不要溢出1000字节的缓冲区。

答案 1 :(得分:0)

总结一下: 如果使用字符串类,则始终会操作共享内存的副本。

两种解决方案: 1.不要使用字符串而是使用标准C方法直接操作char数组(strcat例如附加字符) 2.完成name_list的修改后,将其复制回共享内存。

版本1更快。版本2更简单。