#include<sys/mman.h>
#include<unistd.h>
#include<cstdio>
#include<sys/socket.h>
#include<assert.h>
#include<string.h>
#include<string>
#include<vector>
#include<thread>
#include<chrono>
#include<errno.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<iostream>
#define Buffer_Size 256
char* share_mem = 0;
void func(int sockfd,int& count){
printf("A new thread came!\n");
std::string msg = "Hello father,i am thread " + std::to_string(count);
memset(share_mem + count * Buffer_Size,'\0',Buffer_Size);
strcat(share_mem + count * Buffer_Size,msg.c_str());
int ret = send(sockfd,share_mem + count * Buffer_Size,Buffer_Size - 1,0);
if(ret == -1){
printf("%s\n",strerror(errno));
exit(-1);
}
++count;
}
int main(){
int pipefd[2];
int ret;
ret = socketpair(AF_UNIX,SOCK_STREAM,0,pipefd);
assert(ret != -1);
int shmfd;
const char* shm_name = "/my_shm";
shmfd = shm_open(shm_name,O_CREAT | O_RDWR,0666);
assert(shmfd != -1);
ret = ftruncate(shmfd,Buffer_Size * 10);
assert(ret != -1);
share_mem = (char*)mmap(NULL,Buffer_Size * 10,PROT_READ | PROT_WRITE,MAP_SHARED,shmfd,0);
assert(share_mem != MAP_FAILED);
close(shmfd);
if((ret = fork()) == 0){
printf("I am son\n");
close(pipefd[0]);
std::vector<std::thread>_thread;
int count_son = 0;
for(int i = 0;i < 10;++i){
_thread.push_back(std::thread(func,pipefd[1],std::ref(count_son)));
std::this_thread::sleep_for(std::chrono::seconds(1));
}
for(auto& value:_thread)
value.join();
close(pipefd[1]);
exit(0);
}
else{
printf("I am father\n");
close(pipefd[1]);
int count_father = 0;
while(recv(pipefd[0],share_mem + count_father * Buffer_Size,Buffer_Size - 1,0)){
printf("%s\n",share_mem + count_father * Buffer_Size);
++count_father;
}
close(pipefd[0]);
}
for(int i = 0;i < 10;++i){
printf("%s\n",share_mem + i * Buffer_Size);
}
return 0;
}
- 管道使用socketpair创建,子进程作为写端,父进程作为读端。
- 子进程中创建了10个线程,每个线程在共享内存的不同位置进行写。此处通过线程模拟进程。
- 最后验证共享内存的使用
运行结果截图如下: