共享内存不在进程之间共享
我正在编写一个服务器程序,它从客户端接收消息并向所有以前的客户端广播消息。我需要在进程之间创建共享内存,但共享内存似乎不起作用。
这是我的代码:
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) ;
任何人都可以帮助我吗?非常感谢!
I am writing a server program where it receives message from client and broadcast message to all previous clients. I need to create a shared memory between processes, but it seems that the shared memory is not working.
Here is my code:
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);
}
When I modify name_list in the children process, it seems that this modification is not seen by other processes.
Can anyone give any suggestions? Thanks!!
UPDATE: I tried to change to this as suggested, but still does not work.
name_list = (char*) shmat(shmid2, (void *)0, 0) ;
Anyone can help me on this? Many thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
当您将
std::string
对象name_list
分配给从共享内存获取的指针时:您正在调用字符串的赋值运算符,该运算符复制 赋予新内存的指针。当您的代码操作
name_list
时,它会操作副本,而不影响共享内存。看起来您正在尝试从一个进程写入共享内存,并在另一个进程中读取共享内存,这不是一个需要解决的小问题。确定哪个进程可以读取和写入哪些内存是很棘手的,维护缓存一致性也是如此。查找生产者-消费者环形缓冲区(在 Google 上或在 Stack Overflow 上)以获取此问题的一些标准解决方案。
要回答您最初的问题,一旦您在本地内存中操作了字符串,您需要将其放回共享内存中。这将在紧要关头完成:
您还可以直接操作共享内存,使用指针
shm2
,直接使用 C 指针,注意不要溢出您的 1000 字节缓冲区。When you assign the
std::string
objectname_list
to the pointer you get from shared memory:you're calling the string's assignment operator, which copies the pointer it's given into new memory. When your code manipulates
name_list
, it's manipulating the copy, leaving shared memory untouched.It looks like you're trying to write to shared memory from one process, and read from it in another process, which is not a trivial problem to solve. Figuring out which process can read and write which pieces of memory is tricky, as is maintaining cache coherency. Look up producer-consumer circular ring buffers (either on Google or here on Stack Overflow) for some standard solutions to this problem.
To answer your original question, once you've manipulated the string in local memory, you need to put it back in shared memory. This will do in a pinch:
You could also manipulate shared memory directly, using the pointer
shm2
, using C pointers directly, taking care not to overflow your 1000-byte buffer.总结一下:
如果您使用字符串类,您将始终操作共享内存的副本。
两种解决方案:
1.不要使用字符串而是使用标准C方法直接操作char数组(例如strcat附加字符)
2. 修改完 name_list 后,将其复制回共享内存。
版本 1 更快。版本 2 更简单。
To summarize:
If you use string class, you will always manipulate a copy of the shared memory.
Two solutions:
1. Don't use string but standard C method to directly manipulate the char array (strcat for example to append characters)
2. Once you have finished modifying your name_list, copy it back to the shared memory.
Version 1 is faster. Version 2 is simpler.