In this chapter we shall learn about:
1. Introduction
2. How to create a shared segment?
3. How to attach a shared segment?
4. How to read and write in shared memory?
5. How to detach segments?
6. How to delete the segment?
7. Full Program for shared memory
Introduction:
1. Shared memory is used to share the same resources between multiple processes.
2. If means that you allocate a block of memory and many process can access that memory.
3. Now, you might be thinking if multiple resources access the same memory, will there be race condition?
4. True, there will be race condition, for that to resolve we need to use semaphores. We shall see that in the next chapter.
Now let us see how to create a shared memory with series of simple steps and then see the full program.
1. How to create a shared segment?
To create and connect a segment we should use “shmget()” system call.
The function prototype is :
int shmget(key_t key, size_t size, int shmflg);
Here:
key : It is a unique identifier, if any process wants to connect to the queue, it should have to use the same key.
As key is a “long” data type, you can use any integer to set the key.
Or you can also use “ftok()” known as “file to key”. The function accepts 2 arguments, first is file path and the next is a id. “ftok()” will use these 2 arguments and then will create a unique key. The other program trying to access this queue should use the same parameters.
Function prototype for ftok is:
key_t ftok(const char *path, int id);
size : It is the size in bytes of the shared memory segment.
shmflg : It is used to set the permissions of the segment bitwise-ORd with IPC_CREAT, to create a segment.
Below is how you create a segment:
key_t key; int shmid; key = ftok("/home/aj/myFile", 'R'); shmid = shmget(key, 1024, 0644 | IPC_CREAT);
I have created a segment of 1Kb.
2. How to attach a shared segment?
Now that you have created a shared segment, how to get the pointer to that segment?
For that we need to attach to the segment by using “shmat()” system call. This system call will return the pointer to the shared memory segment.
The function prototype for “shmat()” is:
void *shmat(int shmid, void *shmaddr, int shmflg);
Here:
shmid: It is the shared memory ID you got from the call to shmget().
shmaddr : It is to specify which specific address to use. It is important to set it to 0 and let the OS choose the address for you.
shmflg : YOu can set it to SHM_RDONLY if you only want to read from it, 0 otherwise.
Here is an example for shmget and shmat
key_t key; int shmid; char *data; key = ftok("/home/aj/myFile", 'R'); shmid = shmget(key, 1024, 0644 | IPC_CREAT); data = shmat(shmid, (void *)0, 0);
Note:
shmat() returns -1 on failure. As it is an integer, you need to cast during the comparison to check for errors.
Example:
data = shmat(shmid, (void *)0, 0); if (data == (char *)(-1)) perror("shmat");
3. How to read and write in shared memory?
You can use the pointer to read and write. In our example it will be the pointer with the name “data” in above example.
4. How to detach segments?
You can use “shmdt()” system call to detach the segment. The prototype is:
int shmdt(void *shmaddr);
5. How to delete the segment?
When you detach, the shared memory is present but you have detached form it. To destroy the shared memory you need to use “shmctl()” system call.
shmctl(shmid, IPC_RMID, NULL);
Full Program for shared memory:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #define SHM_SIZE 1024 int main(int argc, char *argv[]) { key_t key; int shmid; char *data; int mode; key = 1234; /*if ((key = ftok("shmdemo.c", 'R')) == -1) { perror("ftok"); exit(1); }*/ /* connect to the segment: */ if ((shmid = shmget(key, SHM_SIZE, 0644 | IPC_CREAT)) == -1) { perror("shmget"); exit(1); } /* attach to the segment to get a pointer to it: */ data = shmat(shmid, (void *)0, 0); if (data == (char *)(-1)) { perror("shmat"); exit(1); } /*Write into the segment*/ printf("Writing to segment: \"%s\"\n", argv[1]); strncpy(data, argv[1], SHM_SIZE); /* Reading from the segment*/ printf("Reading form the segment: \"%s\"\n", data); /* detach from the segment: */ if (shmdt(data) == -1) { perror("shmdt"); exit(1); } return 0; }
Output:
You need to input the data when you are executing the program as “./a.out www.prodevelopertutorial.com”
Writing to segment: "www.prodevelopertutorial.com" Reading form the segment: "www.prodevelopertutorial.com"
List Of Tutorials available in this website: