With shared memory attach / detach / deallocate

I have a question regarding shared memory segmentation in c using POSIX system calls. Is it right that I disconnect and delete the segment from the client and server, or do I just need to delete it from the server?

I have 2 programs

One for the server and one for the client

the steps for the server 1)create memory segment 2)attach 3)detach 4)remove steps for the client 1)create 2)attach 3)detach 4)remove 

this is my code:

 //server #include<stdlib.h> #include<stdio.h> #include<sys/ipc.h> #include<sys/types.h> #include<sys/wait.h> #include<sys/shm.h> #define SHMSZ 100 int main() { key_t key; char c; int shmid; char *shm; key=1025; //locate if((shmid=shmget(key,SHMSZ,0666 | IPC_CREAT))<0) { perror("shmget"); exit(-1); } //attach if((shm=shmat(shmid,NULL,0))==(char*)-1) { perror("shmat"); exit(-1); } sprintf(shm,"Hi there"); //shm="Hi There"; while(*shm!='*'); sleep(1); //detach shmctl(shmid,IPC_RMID,NULL); return 0; } 

this is the client side

 //client #include<stdlib.h> #include<stdio.h> #include<sys/ipc.h> #include<sys/types.h> #include<sys/wait.h> #include<sys/shm.h> #define SHMSZ 100 int main() { key_t key; int shmid; char c; char *shm, *s; key=1025; //locate if((shmid=shmget(key,SHMSZ,0666 | IPC_CREAT))<0) { perror("shmget"); exit(-1); } //attach if((shm=shmat(shmid,NULL,0))==(char*)-1) { perror("shmat"); exit(-1); } printf("%s\n",shm); *shm='*'; shmdt(&shmid); shmctl(shmid, IPC_RMID,NULL); return 0; } 
+4
source share
1 answer

Since you are using System V IPC, not POSIX IPC, check the shm_nattch value in the data structure associated with the shared memory segment identifier. You can get this value by calling shmctl with the IPC_STAT flag. Calling shmdt will decrease this value by one, and the last process to call this function will set shm_nattach to 0 . Once the value is reset, you can safely make a shmctl call to remove the memory segment.

Thus, in both your client’s code and the server’s code, if the server cannot survive the client’s wait, you should check the shm_nattch value with a separate shmctl call after the shmdt call to find out the processes accessing the shared memory segment have been reduced to to zero. You should also make sure that the IPC_STAT call is checked for errors to avoid a race condition where two separate processes call shmdt , decreasing the value of shm_nattch to zero, but the process that was actually the last shmdt call is suspended by the OS, and the other process sees that the value of shm_nattch is equal to zero and deletes the memory segment. Since shm_ctl calls are required to verify and delete the shared memory shm_ctl , and this call will fail if the shared memory segment identifier is invalid, theoretically you should not work in any race conditions if you only make shm_ctl or shmdt calls after how one process deleted a shared memory segment. What you want to avoid will have access to a pointer to a shared memory segment after it is deleted. Checking for failed calls to shm_ctl will help you avoid such situations. In other words, if the call fails, you cannot safely access the pointer.

If, on the other hand, your server certainly outlives any of the clients, then the server can safely make a call to delete the shared memory segment, since this will be the last process using it ... all other clients will not need to delete the memory segment, but just disconnect from it.

+6
source

Source: https://habr.com/ru/post/1389354/


All Articles