您的位置:首页 > 运维架构 > Linux

Linux 编程 共享内存

2012-09-18 22:35 417 查看
  关于共享内存的操作,要用到shmget、shmat、shmctl、shmdt这几个函数,详细说明请大家查看手册

  调试的时候可以使用命令ipcs,ipcs -m可以看到共享内存的情况,ipcs -s可以看到信号量的使用情况

以下是我对这几个函数的封装

#ifndef SHAREDMEMORY_H
#define SHAREDMEMORY_H

#include <sys/shm.h>

#define READ_WRITE_FLAG (S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH)

class SharedMemory
{
public:
SharedMemory(key_t key,size_t size,const int option);
void* SharedMemoryMat();
void Detach(void* sharedMemory);
void DeleteSharedMemory();

private:
int shmID;
};

#endif


SharedMemory.cpp

#include "SharedMemory.h"
#include "SharedMemoryException.h"

SharedMemory::SharedMemory(key_t key,size_t size,const int option)
{
shmID=shmget(key,size,option);
if(shmID==-1)
throw SharedMemoryException("Failed to get shared memory");
}

void* SharedMemory::SharedMemoryMat()
{
//use (void*)0 to let system select the address of shared memory
void* sharedMemory=shmat(shmID,(void*)0,0);
if(sharedMemory==(void*)-1)
throw SharedMemoryException("Failed in shmat");

return sharedMemory;
}

void SharedMemory::Detach(void* sharedMemory)
{
if(shmdt(sharedMemory)==-1)
throw SharedMemoryException("Failed to delete shared memory");
}

void SharedMemory::DeleteSharedMemory()
{
if(shmctl(shmID,IPC_RMID,0)==-1)
throw SharedMemoryException("Failed to detach shared memory");
}


然后进程之间还要额外进行同步,这里使用信号量进行同步(注意进程同步的信号量与线程的是不一样的)

#ifndef SEMAPHORE_H
#define SEMAPHORE_H

#include <sys/sem.h>
#include <sys/stat.h>

union semun
{
int              val;    /* Value for SETVAL */
struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
unsigned short  *array;  /* Array for GETALL, SETALL */
struct seminfo  *__buf;  /* Buffer for IPC_INFO
(Linux-specific) */
};

#define READ_WRITE_FLAG (S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH)

class Semaphore
{
public:
Semaphore(key_t key,int option);
//initialize semaphore
bool SetSemValue(const int value);
bool DeleteSemValue();
bool SemaphoreP();
bool SemaphoreV();
bool SemaphoreOp(const int op);

private:
void SetSemBuf(struct sembuf* semb,const int op);
int semID;
};

#endif


注意union semun可能要自己定义,最好按照手册上的来定义(man semctl)

Semaphore.cpp

View Code

//============================================================================
// Name        : sharedMem_Consumer.cpp
// Author      : Lei
// Version     :
// Copyright   :
// Description : sharedMem_Consumer in C++, Ansi-style
//============================================================================

#include <iostream>
#include "Semaphore.h"
#include "SharedMemory.h"
#include <string.h>
#include <stdlib.h>
using namespace std;

int main()
{
int pauseTime;
void* sharedMemory=static_cast<void*>(0);

//use semaphore to synchronize processes
//we had initialized semaphore in producter
//so we don't call Semaphore::SetValue() here
Semaphore semaphore(static_cast<key_t>(1234),READ_WRITE_FLAG);

//manager shared memory
SharedMemory shManager(static_cast<key_t>(1234),sizeof(char)*1024,READ_WRITE_FLAG);
sharedMemory=shManager.SharedMemoryMat();

bool running=true;
while(running)
{
if(semaphore.SemaphoreP()==false)
running=false;

cout<<"Press Y/y to read message from producter: ";
char ch;
cin>>ch;
char message[1024];
strcpy(message,static_cast<char*>(sharedMemory));
cout<<message<<endl;

if(strcmp(static_cast<char*>(sharedMemory),"end")==0)
running=false;

if(semaphore.SemaphoreV()==false)
running=false;

pauseTime=rand()%2;
sleep(pauseTime);
}

shManager.Detach(sharedMemory);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: