进程同步之共享内存
- 一个进程内可以有多个线程,进程内的多个线程可以共享当前进程的资源
- 进程共享计算机资源
- 在某种程度上,多进程是共同使用物理内存的
- 由于操作系统的进程管理,进程间的内存空间是独立的
- 进程默认是不能访问进程空间之外的内存空间的,但是通过共享内存就可以打破这样的限制,有了共享内存,进程就可以通过页表映射到同样的一片内存中去
共享内存的方法
- 共享存储允许不相关的进程访问同一片物理内存
- 共享内存是两个进程之间共享和传递数据最快的方式
- 共享内存未提供同步机制,需要借助其他机制管理访问
使用共享内存大概的四个步骤
- 申请共享内存
- 连接到进程空间
- 使用共享内存
- 脱离进程共建&删除
例子
- 客户端 -> 共享内存 -> 服务端
#include "common.h"
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
int main()
{
// 共享内存的结构体
struct ShmEntry *entry;
// 1. 申请共享内存
int shmid = shmget((key_t)1111, sizeof(struct ShmEntry), 0666|IPC_CREAT);
if (shmid == -1){
std::cout << "Create share memory error!" << std::endl;
return -1;
}
// 2. 连接到当前进程空间/使用共享内存
entry = (ShmEntry*)shmat(shmid, 0, 0);
entry->can_read = 0;
while (true){
if (entry->can_read == 1){
std::cout << "Received message: " << entry->msg << std::endl;
entry->can_read = 0;
}else{
std::cout << "Entry can not read. Sleep 1s." << std::endl;
sleep(1);
}
}
// 3. 脱离进程空间
shmdt(entry);
// 4. 删除共享内存
shmctl(shmid, IPC_RMID, 0);
return 0;
}
#include "common.h"
#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
int main()
{
struct ShmEntry *entry;
// 1. 申请共享内存
int shmid = shmget((key_t)1111, sizeof(struct ShmEntry), 0666|IPC_CREAT);
if (shmid == -1){
std::cout << "Create share memory error!" << std::endl;
return -1;
}
// 2. 连接到当前进程空间/使用共享内存
entry = (ShmEntry*)shmat(shmid, 0, 0);
entry->can_read = 0;
char buffer[TEXT_LEN];
while (true){
if (entry->can_read == 0){
std::cout << "Input message>>> ";
fgets(buffer, TEXT_LEN, stdin);
strncpy(entry->msg, buffer, TEXT_LEN);
std::cout << "Send message: " << entry->msg << std::endl;
entry->can_read = 1;
}
}
// 3. 脱离进程空间
shmdt(entry);
// 4. 删除共享内存
shmctl(shmid, IPC_RMID, 0);
return 0;
}
export CC=gcc
export CPP=g++
export CFLAGS= -g -lpthread
CSRCS = $(wildcard *.c)
COBJS = $(patsubst %.c, %, $(CSRCS))
CPPSRCS = $(wildcard *.cpp)
CPPOBJS += $(patsubst %.cpp, %, $(CPPSRCS))
CHEADERS = $(wildcard *.h)
OBJ = $(COBJS)
OBJ += $(CPPOBJS)
all: $(OBJ)
%:%.c $(CHEADERS)
$(CC) $^ -o $@ $(CFLAGS)
%:%.cpp $(CHEADERS)
$(CPP) $^ -o $@ $(CFLAGS)
clean:
rm *.o $(OBJ) -rf
.PHONY:clean
Success
共享存储是两个进程之间共享和传递数据最快的一种方式
共享内存未提供同步机制,需要借助其他机制管理访问
共享内存是高性能后台开发中最常用的进程同步方式