简体   繁体   中英

shared memory is not shared between processes

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!

When you assign the std::string object name_list to the pointer you get from shared memory:

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

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:

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

You could also manipulate shared memory directly, using the pointer shm2 , using C pointers directly, taking care not to overflow your 1000-byte buffer.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM