Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.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++ 进程之间不共享共享内存_C++_Network Programming_Fork_Shared Memory - Fatal编程技术网

C++ 进程之间不共享共享内存

C++ 进程之间不共享共享内存,c++,network-programming,fork,shared-memory,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) { p

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

这是我的密码:

 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);
  }

有人能帮我吗?非常感谢

std::string
对象
name\u列表
分配给从共享内存获取的指针时:

string name_list;
// ...
shm2 = shmat(shmid2, (void *)0, 0) ;
name_list= (char*) shm2;
// ...
name_list.append(message);
您正在调用字符串的赋值运算符,它将给定的指针复制到新内存中。当您的代码操纵
name\u list
时,它操纵的是副本,而共享内存保持不变

看起来您正试图从一个进程写入共享内存,然后在另一个进程中读取,这不是一个需要解决的小问题。弄清楚哪个进程可以读取和写入哪些内存是一件棘手的事情,就像保持缓存一致性一样。查找生产者-消费者环形缓冲区(在Google上或这里的堆栈溢出上)以获得此问题的一些标准解决方案

要回答最初的问题,在本地内存中操作字符串后,需要将其放回共享内存中。这将在紧要关头完成:

if(name_list.size() <= 1000) {
    memcpy(shm2, name_list.data(), name_list.size());
} else {
    // error: name list overflowed shared memory
}
if(name_list.size()总结:
如果您使用string类,您将始终操作共享内存的副本

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


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

1:请修正缩进,你的代码很难读懂。2:你如何“修改名称列表”?修改它指向的内存,或者修改变量?顺便说一句,请包含变量声明Fixed。你知道为什么这不起作用吗?嗨,准将,你的答案似乎接近s解决方法。如果我在这里很愚蠢,请原谅,但我仍然不明白我为什么不改变共享内存。请您详细解释一下好吗?谢谢!!我也这么想。@Qii:
name\u list=(char*)shm2;
创建一个字符串。在字符串构造函数中,它复制数据。因此,当您更改名称列表时,它正在更改与字符无关的变量*您以这种方式构造对象(再次是因为它被复制)。为了使事情更简单,我建议不要使用对象,而是使用原始数据(整数、字符、浮点和数组以及简单结构)感谢Commodore和acidzombie24!我花了几个小时试图找出哪里出了问题。现在这是一个很大的解脱。嗨,伙计们,坏消息,我按照建议尝试了name_list=(char*)shmat(shmid2,(void*)0,0),但仍然不起作用。。
if(name_list.size() <= 1000) {
    memcpy(shm2, name_list.data(), name_list.size());
} else {
    // error: name list overflowed shared memory
}