关于信号量和共享内存的相关知识可参考下面链接:
进程间通信方式介绍_夜雨听萧瑟的博客-CSDN博客
C++ 创建共享内存_c共享内存_夜雨听萧瑟的博客-CSDN博客
信号量SytemV与Posix信号量的介绍与用法_夜雨听萧瑟的博客-CSDN博客
直接上代码,代码如下:
#include <iostream>
#include <string>
#include <unistd.h>
#include <errno.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <string.h>
#define SHARE_MEM_SIZE 2048
class Semaphore
{
private:
union semVar
{
int val;
struct semid_ds *buf;
unsigned short *array;
};
int sem_id;
public:
bool init(key_t key);
bool wait();
bool post();
bool destroy();
};
bool Semaphore::init(key_t key)
{
sem_id = semget(key,0,0640);
if(-1 == sem_id)
{
if(2 == errno)
{
sem_id = semget(key,1,0640|IPC_CREAT);
if(-1 == sem_id)
{
std::cout << "init 1 semget() error" << std::endl;
return false;
}else
{
union semVar semTmp;
semTmp.val = 1;
if(semctl(sem_id,0,SETVAL,semTmp) < 0)
{
std::cout << "init 1 semctl() error" << std::endl;
return false;
}else
{
return true;
}
}
}else
{
std::cout << "init 2 semget() error" << std::endl;
return false;
}
}else
{
return true;
}
}
bool Semaphore::wait(){
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = -1;
sem_b.sem_flg = SEM_UNDO;
if(-1 == semop(sem_id,&sem_b,1))
{
std::cout << "wait semop failed." << std::endl;
return false;
}
return true;
}
bool Semaphore::post()
{
struct sembuf sem_b;
sem_b.sem_num = 0;
sem_b.sem_op = 1;
sem_b.sem_flg = SEM_UNDO;
if(-1 == semop(sem_id,&sem_b,1))
{
std::cout << "post semop failed." << std::endl;
return false;
}
return true;
}
bool Semaphore::destroy()
{
if(semctl(sem_id,0,IPC_RMID) == -1)
{
std::cout << "destroy semctl failed." << std::endl;
return false;
}
return true;
}
int main()
{
Semaphore sem;
//初始化信号灯
if(false == sem.init(0x5000))
{
std::cout << "sem init failed." << std::endl;
return -1;
}
std::cout << "sem init ok." << std::endl;
int shmid = 0; //内存标识符
//创建共享内存
shmid = shmget((key_t)0x5005,SHARE_MEM_SIZE,0640|IPC_CREAT);
if(-1 == shmid)
{
std::cout << "create shareMem failed." << std::endl;
return -1;
}
char* pMemSharedMem = 0;
///
//等待信号灯挂出,等待成功后,将持有锁
if(false == sem.wait())
{
std::cout << "sem wait failed." << std::endl;
return -1;
}
std::cout << "sem wait ok." << std::endl;
sleep(10);
//将当前进程与共享内存shmid建立链接,shmat返回指定共享内存的映射地址
pMemSharedMem = (char*)shmat(shmid,0,0);
std::cout << "read context: " << pMemSharedMem << std::endl;
std::string strContext = "hello world, "+ std::to_string(getpid());
strncpy(pMemSharedMem,strContext.c_str(),strContext.length());
std::cout << "write after: " << pMemSharedMem << std::endl;
//shmat的反操作,将共享内存与当前进程分离
shmdt(pMemSharedMem);
//挂出信号灯
if(false == sem.post())
{
std::cout << "sem post failed." << std::endl;
return -1;
}
std::cout << "sem post ok." << std::endl;
//销毁信号灯
//if(false == sem.destroy())
//{
// std::cout << "sem destroy failed." << std::endl;
// return -1;
//}
//std::cout << "sem destroy ok." << std::endl;
return 0;
}
同时运行3个进程,运行结果如下: