On Linux intercommunication with using shared memory API is more elegant than on Windows.
Example sequence of calls for shared memory server is:
Shared memory server
Example sequence of calls for shared memory server is:
- Call ftok function and receive key for shared memory segment.
- Call shmget with IPC_CREAT to create new shared memory segment.
- Call shmat to attach to shared memory array. Do some operations with shared memory.
- Call shmdt to detach from shared memory array.
- Call shmctl with IPC_RMID to remove shared memory segment.
Here is an example of shared memory server which writes Hello World message to shared memory and waits for pressing of any key:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <cstring>
#include <fcntl.h>
int main(int argc, char ** argv)
{
key_t key = ftok(argv[0], 1);
if (key < 0)
{
perror("ftok"); /*Displays the error message*/
return -1;
}
printf("Key for shared memory: '%s'\n", argv[0]);
int shmid = shmget(key, 4096, IPC_CREAT | O_EXCL | S_IRUSR | S_IWUSR);
if(shmid == -1)
{
fprintf(stderr, "Failed to create memory segment. %s\n",
strerror(errno));
return -1;
}
void * pAddr = shmat(shmid, NULL, 0);
if((long long )pAddr == -1)
{
if(shmctl(shmid, IPC_RMID, NULL) == -1)
{
fprintf(stderr, "Failed to remove shared memory segment. %s\n",
strerror(errno));
return -1;
}
fprintf(stderr, "Failed to attach to shared memory. %s\n",
strerror(errno));
return -1;
}
const char * szcServerMessage = "Hello world!";
strcpy((char *) pAddr, szcServerMessage);
printf("Server put message to shared memory.\n");
printf("Press any key for exit ...\n");
getchar();
if(shmdt(pAddr) == -1)
{
fprintf(stderr, "Failed to detach from shared memory segment. %s\n",
strerror(errno));
return -1;
}
if(shmctl(shmid, IPC_RMID, NULL) == -1)
{
fprintf(stderr, "Failed to remove shared memory segment. %s\n",
strerror(errno));
return -1;
}
return 0;
}
Shared memory client
Example sequence of calls for shared memory client is:- Call ftok function and receive key for shared memory segment.
- Call shmget to obtain pointer to existing shared memory segment descriptor.
Don't set IPC_CREAT flag, besides instead memory size you can simply pass 0. - Call shmat to attach to shared memory array. Do some operations with shared memory.
- Call shmdt to detach from shared memory array.
Please notice that on client side you shouldn't call shmctl with IPC_RMID, because shared segment was created on server side, but not on client.
Here is implementation of shared memory client that attaches to the shared memory segment and then reads message:
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <cstring>
#include <fcntl.h>
int main(int argc, char ** argv)
{
key_t key = ftok("./server", 1);
if (key < 0)
{
perror("ftok"); /*Displays the error message*/
return -1;
}
int shmid = shmget(key, 0, S_IRUSR | S_IWUSR);
if(shmid == -1)
{
fprintf(stderr, "Failed to create memory segment. %s\n",
strerror(errno));
return -1;
}
void * pAddr = shmat(shmid, NULL, 0);
if((long long )pAddr == -1)
{
fprintf(stderr, "Failed to attach to shared memory. %s\n",
strerror(errno));
return -1;
}
char szcBufferMessage[4096];
strcpy(szcBufferMessage, (char *) pAddr);
printf("Client read message from shared memory: %s \n", szcBufferMessage);
printf("Press any key for exit ...\n");
getchar();
if(shmdt(pAddr) == -1)
{
fprintf(stderr, "Failed to detach from shared memory segment. %s\n",
strerror(errno));
return -1;
}
/* In client we shouldn't delete any segment, because it is allocated by server */
return 0;
}
Server's output example:
$ ./server
Key for shared memory: './server'
Server put message to shared memory.
Press any key for exit ...
Server put message to shared memory.
Press any key for exit ...
Client's output example:
Client read message from shared memory: Hello world!
Press any key for exit ...
As you can see client successfully reads the message from server.
Hope this post is useful. Good luck!