使用有名信号量保护共享内存,防止数据的不一致。
// #include <iostream>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <iostream>
#include<semaphore.h>
#define PAGE_SIZE 4096
using namespace std;
// 使用信号量进行同步
int main() {
// 创建共享内存
int fd;
void* p;
// 创建一个有名信号量
sem_t *my_sem;
my_sem=sem_open("my7_sem",O_CREAT,0600,1);
fd=open("/dev/zero",O_RDWR);
if(fd<0){
cout<<"open failed\n";
perror("open failed");
return 0;
}
p=(int *)mmap(NULL, 4,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
close(fd);
if(p==MAP_FAILED){
cout<<"map failed\n";
perror("mmap failed");
return 0;
}
*(int*)p=0;
if(fork()==0){
for(int i=0;i<100000;++i){
sem_wait(my_sem);
// sleep(1);
cout<<"1 gggg"<<endl;
(*(int*)p)++;
cout<<"1 hhhh"<<endl;
sem_post(my_sem);
}
}else{
for(int i=0;i<100000;++i) {
sem_wait(my_sem);
cout<<"2 gggg"<<endl;
(*(int*)p)++;
cout<<"2 hhhh"<<endl;
sem_post(my_sem);
}
int stat;
wait(&stat);
cout<<(*(int*)p)<<endl;
munmap(p,sizeof(int));
sem_close(my_sem);
sem_unlink("my_sem");
}
std::cout << "Hello, World!" << std::endl;
return 0;
}
在使用sem_open()
sem_close()
和sem_unlink()时,需要注意死锁的问题,如果正确调用了sem_open创建了一个信号量,那么这个信号量就一直存在于内核中,即使调用了sem_close()关闭信号量,信号量依旧存在与内核中,sem_close()只是阻止了程序使用这个信号量,并不删除信号量,所以需要调用sem_unlink(“the name semaphore”)删除信号量。如果程序异常终止,只会自动调用sem_close()关闭信号量,也不会删除信号量。如果此时信号量值为0,下次执行程序打开信号量的时候,会正常返回信号量,但是调用sem_wait会阻塞进程,因为前面的进程已经死了,无法释放信号量的值。可以在sem_open的时候,使用O_EXCL防止信号量已经存在的情况。
sem_t *my_sem;
my_sem=sem_open("my7_sem",O_CREAT|O_EXCL,0600,1);
if(my_sem==SEM_FAILED){
cout<<"error\n";
sem_unlink("my7_sem");
my_sem=sem_open("my7_sem",O_CREAT,0600,1);
cout<<"delete and recreate\n";
}
ldd和pthread指令
可以使用ldd 查看程序需要的内存。
使用在g++编译时添加-pthread参数。