进程间通信:共享内存+互斥锁
上⼀篇没有实现互斥锁保护,今天⽤信号量实现⼀个进程间互斥锁,保护共享变量的修改。
参考资料:
实现思路:⽗进程开辟⼀段共享内存,将开始sizeof(sem_t)⼤⼩作为互斥锁存储空间,在⽗进程中映射这⼀段内存,在之后fork的⼦进程将会继承这⼀映射关系,进⽽实现进程间共享互斥锁。
代码实现:
进程间通信 共享内存#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <semaphore.h>
#define MAPPING_SIZE 4096
int main (int argc,char* argv[]){
int mapfd;
const char* mapname = "/number";
// 开辟⼀段共享内存
mapfd = shm_open(mapname,O_RDWR|O_CREAT,S_IRUSR | S_IWUSR);
if(mapfd == -1){
perror("shm_open fail");
exit(EXIT_FAILURE);
}
// ftruncate可以⽤来设置共享内存到指定⼤⼩
if(ftruncate(mapfd,MAPPING_SIZE) == -1){
perror("ftruncate fail");
close(mapfd);
exit(EXIT_FAILURE);
}
// 将共享内存开始处作为进程间互斥锁
void* sp = mmap(NULL,MAPPING_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,mapfd,0);
if(sp == NULL){
perror("mmap fail");
close(mapfd);
exit(EXIT_FAILURE);
}
sem_t* mutex = (sem_t*)sp;
if(sem_init(mutex,1,1) != 0) {
perror("sem_init fail");
close(mapfd);
exit(EXIT_FAILURE);
}
int * num = (int*)(sp+sizeof(sem_t));
int stat,cid,n,procCount=0,maxProcCount=8;
for(n = 0;n<maxProcCount;++n){
cid = fork();
if (cid == -1){
perror("fork fail");
continue;
}
if(cid == 0){
sem_wait(mutex);
(*num)++;
sem_post(mutex);
printf("Process %d: %d\n",getpid(),*num);
if(munmap(sp,MAPPING_SIZE) == -1){
perror("munmap fail");
}
close(mapfd);
_exit(EXIT_SUCCESS);
}
++procCount;
}
while(procCount--){
cid = wait(&stat);
if(cid == -1){
perror("wait fail");
break;
}
printf("%d cid %d exit.\n",procCount,cid);
}
sem_destroy(mutex);
close(mapfd);
// 如果不执⾏shm_unlink则多次执⾏程序的输出是递增的,共享内存被重复利⽤了    shm_unlink(mapname);
}
运⾏效果:
[root@centos7 c]# gcc -lrt -pthread process.c -o process
[root@centos7 c]# ./process
Process 11086: 1
Process 11087: 2
Process 11088: 3
Process 11089: 4
Process 11090: 5
Process 11092: 6
7 cid 11086 exit.
6 cid 1108
7 exit.
5 cid 11088 exit.
4 cid 11089 exit.
3 cid 11090 exit.
2 cid 11092 exit.
Process 11093: 7
Process 11091: 8
1 cid 11093 exit.
0 cid 11091 exit.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。