IPCの共有メモリ
共有メモリ
*最速のIPCは、操作共有メモリがプロセス-カーネルのデータコピーに関係しないからです.
*プロセス間の操作共有メモリは、信号量などの同期機構が必要です.
データ構造shmid_ds(萼include<sys/shm.h>)
*最速のIPCは、操作共有メモリがプロセス-カーネルのデータコピーに関係しないからです.
*プロセス間の操作共有メモリは、信号量などの同期機構が必要です.
データ構造shmid_ds(萼include<sys/shm.h>)
struct shmid_ds{
struct ipc_perm shm_perm; /* */
int shm_segsz; /* ( )*/
time_t shm_atime; /* */
time_t shm_dtime; /* */
time_t shm_ctime; /* */
unsigned short shm_cpid; /* pid*/
unsigned short shm_lpid; /* 1 pid*/
short shm_nattch; /* */
/* */
unsigned short shm_npages; /* ( )*/
unsigned long *shm_pages; /* frames->SHMMAX */
struct vm_area_struct *attaches; /* */
};
相関関数#include <sys/shm.h>
//
int shmget(key_t key, size_t size, int shmflg)
//
void *shmat(int shmid, const void *shmaddr, int shmflg)
//
int shmdt(const void *shmaddr)
// ,
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
使用例/*
* :
* PS:
* (1 Int ): 0.40S, 0.78S, 39.8S
*/
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
using namespace std;
class CSemLock
{
public:
CSemLock(const char *pSemPath)
{
key_t iSemKey;
if ((iSemKey = ftok(pSemPath, 1)) == -1) {
cout << "Ftok Err" << endl;
exit(-1);
}
if ((iSemId = semget(iSemKey, 1, IPC_CREAT|IPC_EXCL|0666)) == (char *)-1) {
cout << "Semget Err" << endl;
exit(-1);
}
UnLock();
}
~CSemLock()
{
if (semctl(iSemId, 0, IPC_RMID) == -1) {
cout << "Semctl Err" << endl;
exit(-1);
}
}
public:
void Lock()
{
struct sembuf sSem;
sSem.sem_num = 0;
sSem.sem_op = -1;
sSem.sem_flg = 0;
semop(iSemId, &sSem, 1);
}
void UnLock()
{
struct sembuf sSem;
sSem.sem_num = 0;
sSem.sem_op = 1;
sSem.sem_flg = 0;
semop(iSemId, &sSem, 1);
}
private:
key_t iSemKey;
int iSemId;
struct sembuf sSem;
};
int main()
{
key_t iShmKey;
int iShmId;
// Get Shm Key
const char *pShmPath = "/data/home/andyawang/code/ipc/Shm";
if ((iShmKey = ftok(pShmPath, 1)) == -1) {
cout << "Ftok Err" << endl;
return -1;
}
// 1.shmget():
// int shmget(key_t key, size_t size, int shmflg)
// key :IPC Key
// size :0 ,>0 (Byte)
// shmflg :0 ,IPC_CREAT ,IPC_CREAT|IPC_EXCL , , -1
if ((iShmId = shmget(iShmKey, 4096, IPC_CREAT|IPC_EXCL|0666)) == -1) {
cout << "Shmget Err" << endl;
return -1;
}
// 2.shmat():
// void *shmat(int shmid, const void *shmaddr, int shmflg)
// shmid : Id
// shmaddr : , NULL,
// shmflg :SHM_RDONLY ,
char* pShm;
if ((pShm = (char*)shmat(iShmId, NULL, 0)) == (char*)-1) {
cout << "Shmat Err" << endl;
return -1;
}
// Operation Shm
CSemLock mSemLock("/data/home/andyawang/code/ipc/Sem");
struct timeval tvBegin, tvEnd;
gettimeofday(&tvBegin, NULL);
for(int i = 0; i < 100000000; i ++)
{
mSemLock.Lock();
int *pVal = (int *)pShm;
(*pVal) ++;
mSemLock.UnLock();
}
gettimeofday(&tvEnd, NULL);
cout << "Shm Val : " << *(int *)pShm << endl;
cout << "Use Second : " << (tvEnd.tv_sec-tvBegin.tv_sec)+1.0*(tvEnd.tv_usec-tvBegin.tv_usec)/1000000<< endl;
// 3.shmctl(): ,
// int shmctl(int shmid, int cmd, struct shmid_ds *buf)
// shmid : Id
// cmd :IPC_STAT buf,IPC_SET buf ,IPC_RMID
// buf :
if (shmctl(iShmId, IPC_RMID, NULL) == -1) {
cout << "Shmctl Err" << endl;
return -1;
}
return 0;
}