当前位置:网站首页>Interprocess communication (IPC): shared memory
Interprocess communication (IPC): shared memory
2022-07-05 18:41:00 【*Flowers bloom on the street】
Interprocess communication IPC : The Conduit 、 Semaphore 、 Shared memory 、 Message queue 、 Socket
Interprocess communication , Passing information between two processes
Except for sockets , The first few are mainly about the communication between two processes on the same host
Shared memory
Shared memory provides an effective way for multiple processes to share and transfer data . Shared memory is to apply for a piece of space in physical memory first , Multiple processes can map it to their own virtual address space . All processes have access to addresses in shared memory , It's like they're made of malloc The distribution is the same . If a process writes to shared memory data , The changes will be immediately seen by any other process that can access the same shared memory . Because it does not provide a synchronization mechanism , So we usually need to use other mechanisms to synchronize access to shared memory .
Interface
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
int shmget(key_t key, size_t size, int shmflg); // Create shared memory
shmget() Used to create or get shared memory
shmget() Successfully returned... Of shared memory ID, Failure to return -1
key: Different processes use the same key Value can get to the same shared memory
size: When creating shared memory , Specify the size of the shared memory space to request , In bytes
shmflg: contain 9 One bit permission flag
IPC_CREAT IPC_EXCL
IPC_CREAT: Existence opens , Create if it does not exist
IPC_EXCL and IPC_CREAT At the same time, an error will be reported , There is no creation ;
( Permissions are directly added to the back for assignment )
void* shmat(int shmid, const void *shmaddr, int shmflg); // mapping , Map shared memory to the address space of the process
shmat() Map the physical memory of the requested shared memory to the virtual address space of the current process
shmat() The first address of shared memory is returned successfully , Failure to return NULL
shmaddr: General NULL, The system automatically selects the mapped virtual address space
shmflg: A set of flag bits ,SHM_RND( This logo is related to shm_addr A combination of , Used to control the address of shared memory link ) SHM_RDONLY( It makes the connected memory read-only ), If not specified, give 0 Can
int shmdt(const void *shmaddr); // Break mapping
shmdt() Disconnect the current process shmaddr Shared memory mapping to
shmdt() Successfully returns 0, Failure to return -1
shmaddr Return address pointer
int shmctl(int shmid, int cmd, struct shmid_ds *buf); // Control shared memory ,eg: Delete
shmctl() Control shared memory
shmctl() Successfully returns 0, Failure to return -1
cmd: Actions to be taken
IPC_STAT hold shmid__ds The data in the structure is set to the current association value of the shared memory
IPC_SET If the process has sufficient permissions , Set the current association value of shared memory to shmid_dsThe value given in the structure
IPC_RMID Delete shared memory segmentbuf: It's a pointer , It points to a structure that contains shared memory patterns and access permissions .
Code implementation
process a Write data to shared memory , process b Read data from shared memory and display shma.c Code for :
a File input ,b File output
a.c file
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>
int main()
{
// Create shared memory
int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);//key The value is 1234, The shared memory size is 128,IPC_CREAT Existence opens , There is no creation , jurisdiction 0600
if(shmid==-1)
{
printf("shmget err\n");// Create failure
exit(1);
}
// mapping , Map shared memory to the address space of the process
// After the mapping is successful, you can use the pointer s Access this space
char*s=(char*)shmat(shmid,NULL,0);//shmat Itself returns a value void* type , Forced to char*,shmid Shared memory id, to NULL. The system automatically selects that the mapped virtual address space flag bit is not specified as 0
if(s==(char *)-1)
{
printf("shmat err\n");// Mapping failed
exit(1);
}
// Write data to shared memory
strcpy(s,"hello");
shmdt(s);// Break mapping
exit(0);
}
b.c file
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>
int main()
{
// Create shared memory , Get shared memory if it exists
int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);//key The value is 1234, The shared memory size is 128,IPC_CREAT Existence opens , There is no creation , jurisdiction 0600
if(shmid==-1)
{
printf("shmget err\n");// Create failure
exit(1);
}
// mapping , Map shared memory to the address space of the process
// After the mapping is successful, you can use the pointer s Access this space
char*s=(char*)shmat(shmid,NULL,0);//shmat Itself returns a value void* type , Forced to char*,shmid Shared memory id, to NULL. The system automatically selects the mapped virtual address space mark
The niche is not specified as 0
if(s==(char *)-1)
{
printf("shmat err\n");// Mapping failed
exit(1);
}
// use test File reads the value in the shared memory space
printf("read:%s\n",s);
shmdt(s);// Break mapping
exit(0);
}
After the shared memory is created successfully , There will always be , Even if the program is finished , There will be , Unless you delete this shared memory or restart
a.c The file is continuously written ,b.c The file is continuously read
a.c file
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>
int main()
{
// Create shared memory
int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);//key The value is 1234, The shared memory size is 128,IPC_CREAT Existence opens , There is no creation , jurisdiction 0600
if(shmid==-1)
{
printf("shmget err\n");// Create failure
exit(1);
}
// mapping , Map shared memory to the address space of the process
// After the mapping is successful, you can use the pointer s Access this space
char*s=(char*)shmat(shmid,NULL,0);//shmat Itself returns a value void* type , Forced to char*,shmid Shared memory id, to NULL. The system automatically selects that the mapped virtual address space flag bit is not specified as 0
if(s==(char *)-1)
{
printf("shmat err\n");// Mapping failed
exit(1);
}
while(1)
{
printf("input\n");
char buff[128]={0};// Put the input data in buff in
fgets(buff,128,stdin);
strcpy(s,buff);// Write the data to the shared memory first so that you can also read the data with end For the end sign
if(strncmp(buff,"end",3)==0)
{
break;// With end For the end of the input flag
}
}
shmdt(s);// Break mapping
exit(0);
}
b.c file
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>
int main()
{
// Create shared memory , Get shared memory if it exists
int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);//key The value is 1234, The shared memory size is 128,IPC_CREAT Existence opens , There is no creation , jurisdiction 0600
if(shmid==-1)
{
printf("shmget err\n");// Create failure
exit(1);
}
// mapping , Map shared memory to the address space of the process
// After the mapping is successful, you can use the pointer s Access this space
char*s=(char*)shmat(shmid,NULL,0);//shmat Itself returns a value void* type , Forced to char*,shmid Shared memory id, to NULL. The system automatically selects the mapped virtual address space mark
The niche is not specified as 0
if(s==(char *)-1)
{
printf("shmat err\n");// Mapping failed
exit(1);
}
while(1)
{
if(strncmp(s,"end",3)==0)
{
break;// First judge whether it is the end sign , Not output
}
sleep(1);
printf("resf:%s\n",s);// To read data
}
shmdt(s);// Break mapping
exit(0);
}
The operation results are as follows :
We can see ,b You can read the shared memory ,a input data b Can read , But as long as we don't enter new data ,b Just keep reading the last data ,
The result we want is to write once , Read it once , Don't write, don't read , We can go through Semaphore Solve this problem
Use semaphores to control shared memory
At this point, we need two semaphores ,s1,s2
sem.h
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/sem.h>
#define SEM1 0 // The first semaphore
#define SEM2 1 // The second semaphore
#define NUM 2 // The total number of semaphores
union semun
{
int val;// Initial value
};// Define your own
void sem_init();// Semaphore initialization
void sem_p(int index);//P operation , Create two semaphores , Distinguish by subscript
void sem_v(int index);//V operation
void sem_destroy();// The destruction
sem.c
#include"sem.h"
static int semid = -1;// Semaphore id, Only valid in this document
void sem_init()// Semaphore initialization
{
semid = semget((key_t)1234,NUM,IPC_CREAT|IPC_EXCL|0600);//key The value is 1234,SEM A semaphore , Create a new semaphore , If it already exists, an error will be reported , Access rights 0600
if(semid == -1)// New creation failed , Description already exists or creation failed
{
semid=semget((key_t)1234,NUM,0600);
//semid = semget((key_t)1234,SEM,0600);// When the signal already exists , Acquisition semaphore
if(semid == -1)
{
printf("semget err\n");// The previous description of the acquisition failure indicates that the creation failed
}
}
else// Because you want to create NUM A semaphore , Loop initialization
{
union semun a;
int arr[NUM]={1,0};// Semaphore initial value array
for(int i=0;i<NUM;i++)
{
a.val = arr[i];// Initial value of semaphore
if(semctl(semid,i,SETVAL,a)==-1)//i, The number of semaphores .SETVAL,a, Assign initial value to
{
printf("semctl init err\n");// Initialization failed print this statement
}
}
}
}
void sem_p(int index)//P operation
{
if(index<0 || index>=NUM)
{
return;
}
struct sembuf buf;// Changes to semaphores
buf.sem_num=index;// The subscript of the semaphore
buf.sem_op=-1;// What is performed on semaphores is p operation
buf.sem_flg = SEM_UNDO;// Sign a , If the program is abnormal, it can help v operation
if(semop(semid,&buf,1)==-1)
{
printf("semop p err\n");
}
}
void sem_v(int index)//V operation
{
if(index<0 || index>=NUM)
{
return;
}
struct sembuf buf;// Changes to semaphores
buf.sem_num=index;// The subscript of the semaphore
buf.sem_op=1;// What is performed on semaphores is v operation
buf.sem_flg = SEM_UNDO;
if(semop(semid,&buf,1)==-1)
{
printf("semop v err\n");
}
}
void sem_destroy()// The destruction
{
if(semctl(semid,0,IPC_RMID)==-1)//semid Signal to be deleted ,0 placeholder , according to semid Delete all signals created .IPC_RMID Delete semaphores
{
printf("semctl destroy err\n");
}
}
a.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>
#include"sem.h"
int main()
{
// Create shared memory
int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);//key The value is 1234, The shared memory size is 128,IPC_CREAT Existence opens , There is no creation , jurisdiction 0600
if(shmid==-1)
{
printf("shmget err\n");// Create failure
exit(1);
}
// mapping , Map shared memory to the address space of the process
// After the mapping is successful, you can use the pointer s Access this space
char*s=(char*)shmat(shmid,NULL,0);//shmat Itself returns a value void* type , Forced to char*,shmid Shared memory id, to NULL. The system automatically selects the mapped virtual address space mark >
The niche is not specified as 0
if(s==(char *)-1)
{
printf("shmat err\n");// Mapping failed
exit(1);
}
sem_init();// Semaphore initialization
while(1)
{
printf("input\n");
char buff[128]={0};// Put the input data in buff in
fgets(buff,128,stdin);
sem_p(SEM1);// Yes a File first P operation
strcpy(s,buff);// Write the data to the shared memory first so that you can also read the data with end For the end sign
sem_v(SEM2);// Yes b Document carried out v operation , Can't be v The operation is put after the following interpretation , Because if the final output end After the end ,b File cannot be v If the operation obtains permission, it cannot print the last
One
if(strncmp(buff,"end",3)==0)
{
break;// With end For the end of the input flag
}
}
shmdt(s);// Break mapping
exit(0);
}
b.c file
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/shm.h>
#include"sem.h"
int main()
{
// Create shared memory , Get shared memory if it exists
int shmid = shmget((key_t)1234,128,IPC_CREAT|0600);//key The value is 1234, The shared memory size is 128,IPC_CREAT Existence opens , There is no creation , jurisdiction 0600
if(shmid==-1)
{
printf("shmget err\n");// Create failure
exit(1);
}
// mapping , Map shared memory to the address space of the process
// After the mapping is successful, you can use the pointer s Access this space
char*s=(char*)shmat(shmid,NULL,0);//shmat Itself returns a value void* type , Forced to char*,shmid Shared memory id, to NULL. The system automatically selects the mapped virtual address space mark >
The niche is not specified as 0
if(s==(char *)-1)
{
printf("shmat err\n");// Mapping failed
exit(1);
}
sem_init();// Initialize semaphores
while(1)
{
sem_p(SEM2);
if(strncmp(s,"end",3)==0)
{
break;// First judge whether it is the end sign , Not output
}
printf("resf:%s\n",s);// To read data
sem_v(SEM1);
}
shmdt(s);// Break mapping
sem_destroy();// Destroy semaphore
exit(0);
}
Run the program
Running results
边栏推荐
- How to write good code defensive programming
- rust统计文件中单词出现的次数
- node_ Exporter memory usage is not displayed
- 在通达信上做基金定投安全吗?
- Is it safe for golden sun to open an account? Can I open an account free of 5 in case?
- 技术分享 | 接口测试价值与体系
- Cronab log: how to record the output of my cron script
- ClickHouse(03)ClickHouse怎么安装和部署
- Fix vulnerability - mysql, ES
- About statistical power
猜你喜欢
视频自监督学习综述
小程序 修改样式 ( placeholder、checkbox的样式)
A2L file parsing based on CAN bus (3)
Memory leak of viewpager + recyclerview
LeetCode 6109. Number of people who know the secret
Thoroughly understand why network i/o is blocked?
彻底理解为什么网络 I/O 会被阻塞?
Take a look at semaphore, the current limiting tool provided by JUC
2022年阿里Android高级面试题分享,2022阿里手淘Android面试题目
Fix vulnerability - mysql, ES
随机推荐
How to automatically install pythn third-party libraries
lombok @Builder注解
ConvMAE(2022-05)
生词生词生词生词[2]
c语言简便实现链表增删改查「建议收藏」
金太阳开户安全吗?万一免5开户能办理吗?
Reading notes of Clickhouse principle analysis and Application Practice (5)
What is text mining? "Suggested collection"
【Autosar 十四 启动流程详解】
Exemple Quelle est la relation entre le taux d'échantillonnage, l'échantillon et la durée?
Is it safe for golden sun to open an account? Can I open an account free of 5 in case?
记录Pytorch中的eval()和no_grad()
Pytorch yolov5 training custom data
Reptile 01 basic principles of reptile
Simple query cost estimation
vulnhub之darkhole_2
兄弟组件进行传值(显示有先后顺序)
IDEA配置npm启动
Use of websocket tool
Deep copy and shallow copy [interview question 3]