shm stuff
shm stuff
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <string.h>
#include <sys/wait.h>
#define SHM_SIZE 1024
int main() {
int shmid;
char *shm;
shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
if (shmid == -1) {
perror("shmget");
exit(1);
}
shm = (char *)shmat(shmid, NULL, 0);
if (shm == (char *)-1) {
perror("shmat");
exit(1);
}
strcpy(shm, "Hello from Parent");
printf("Parent wrote: %s\n", shm);
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
} else if (pid == 0) {
shm = (char *)shmat(shmid, NULL, 0);
if (shm == (char *)-1) {
perror("shmat");
exit(1);
}
printf("Child read: %s\n", shm);
strcpy(shm, "Hello from Child");
printf("Child wrote: %s\n", shm);
if (shmdt(shm) == -1) {
perror("shmdt");
exit(1);
}
exit(0);
} else {
wait(NULL);
printf("Parent read: %s\n", shm);
if (shmdt(shm) == -1) {
perror("shmdt");
exit(1);
}
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(1);
}
}
return 0;
}
First explain what shared mem is
● This line is defining a constant SHM_SIZE with 1024 bytes. This sets the size of the
shared memory segment. (Think of it as allocating a block of 1024 bytes so that all both
processes can use)
● shmget() : Is the system call to create a new shared memory segment or access an
already existing one. To use these we need to invoke <sys/ipc.h> as a header file.
● IPC_PRIVATE: a key indicating that a unique shared memory segment is created.
Restricting access to it only by inheritance. Only through fork can one gain access to the
shared memory created.
● SHM_SIZE: Allocates 1024 bytes as defined by our macro.
● Flags that we need to pass
○ 0666
■ Sets the permissions so that the segment is readable and writable by the
owner, group, and others.
○ IPC_CREAT
■ Inform the system to create the segment if it does not already exist
● shmat(): This function attaches the shared memory segment (identified by shmid) to
the process’s address space.
● Arguments:
○ shmid: The shared memory identifier returned by shmget().
○ NULL: Let the system choose the best address to attach the segment.
○ 0: Specifies the default read/write mode.
● The returned pointer shm is the starting address of the shared memory block in the
process's address space. If the attachment fails, shmat() returns (char *)-1.
strcpy(shm, "Hello from Parent");
printf("Parent wrote: %s\n", shm);
if (pid == 0) {
shm = (char *)shmat(shmid, NULL, 0);
if (shm == (char *)-1) {
perror("shmat");
exit(1);
}
printf("Child read: %s\n", shm);
strcpy(shm, "Hello from Child");
printf("Child wrote: %s\n", shm);
if (shmdt(shm) == -1) {
perror("shmdt");
exit(1);
}
exit(0);
}
● Now the child process inherits memory mappings from the parent so we technically do
not need to reinitialise shm, it's a good practice tho.
● Child read the message from shm and prints it
● Then the child overwrites the content of shared memory.
● shmdt() is used to detach the shared memory segment from childs address space, thus
the child now no longer has access to that memory. (It still exists, just not accessible.)
wait(NULL);
printf("Parent read: %s\n", shm);
if (shmdt(shm) == -1) {
perror("shmdt");
exit(1);
}
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(1);
}
Normal output:
Gdb time live karte he
Commands in case i forget
Info inferiors
Inferior 1
print shmid
Print shm
https://limewire.com/d/b3444326-561b-40b6-bfc7-9e40a855216d#fTd8fBMYX-wRZi4t6E2TQok
RwVaqtadcoso9lkYOV5s