1. 概念原理
2. Semphore.h
#ifndef SEMPHORE_H
#define SEMPHORE_H
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include "Typedef.h"
class CSem
{
private:
key_t m_key;
int m_semID;
public:
CSem(){};
~CSem(){};
int InitSem(BYTE bBankNo, BYTE bSectNo, BYTE bIdx, int iSemVal);
void P();
void V();
void DelSem();
int GetSemID(){return m_semID;};
};
#endif //SEMPHORE_H
3. Semphore.cpp
#include<sys/stat.h>
#include "Semphore.h"
//描述:初始化信号量
//参数:@bBankNo BANK索引号
// @bSectNo SECT索引号
// @bIdx 对应索引
// @iSemVal 信号量值,默认为1
//返回:失败小于0,反之成功
int CSem::InitSem(BYTE bBankNo, BYTE bSectNo, BYTE bIdx, int iSemVal)
{
m_key = (bBankNo<<16) | (bSectNo<<8) | bIdx;
m_key += 1;
if((m_semID=semget(m_key, 1, IPC_CREAT)) < 0)
{
if ((m_semID=semget(m_key, 1, IPC_CREAT|IPC_EXCL|0666)) < 0)
{
printf("InitSem: semget error!\n");
exit(1);
}
}
if (access("/tmp/InitSemFlg", F_OK) != 0) //处理多个进程各自初始化不统一
{
system("touch /tmp/InitSemFlg");
semctl(m_semID, 0, SETVAL, iSemVal); //只能初始化一次
printf("touch /tmp/InitSemFlg\n");
}
printf("m_key=0x%08x.\n", m_key);
return m_semID;
}
//描述:获取信号量
void CSem::P()
{
struct sembuf op;
memset(&op, 0, sizeof(op));
op.sem_num = 0;
op.sem_op = -1;
op.sem_flg = SEM_UNDO;
semop(m_semID, &op, 1);
}
//描述:释放信号量
void CSem::V()
{
struct sembuf op;
memset(&op, 0, sizeof(op));
op.sem_num = 0;
op.sem_op = 1;
op.sem_flg = SEM_UNDO;
semop(m_semID, &op, 1);
}
void CSem::DelSem()
{
semctl(m_semID, 0, IPC_RMID);
}
4. main()测试函数
#include<sys/stat.h>
#include "Semphore.h"
int main(int argc, char *argv[])
{
int iThrdNo;
if (argc != 2)
{
printf("main: argc must be equal to 2.\n");
exit(-1);
}
iThrdNo = atoi(argv[1]);
CSem *pCSem;
pCSem = new CSem();
if (pCSem == NULL)
{
printf("pCSem == NULL.\n");
exit(-1);
}
pCSem->InitSem(1, 1, 0, 1);
if (iThrdNo == 1)
{
printf("before getval: %d\n", semctl(pCSem->GetSemID(), 0, GETVAL));
pCSem->P();
printf("ThrdNo=%d, P.\n", iThrdNo);
while (getchar() == 'c')
break;
pCSem->V();
printf("ThrdNo=%d, V.\n", iThrdNo);
}
else
{
printf("before getval: %d\n", semctl(pCSem->GetSemID(), 0, GETVAL));
pCSem->P();
printf("ThrdNo=%d, P.\n", iThrdNo);
pCSem->V();
printf("ThrdNo=%d, V.\n", iThrdNo);
}
}
5. 交叉编译
root@ubuntu:/data/# arm-linux-gnueabi-g++ -o Semphore Semphore.cpp -ldl -lrt
6. 测试运行(同步运行)
6.1 运行1号进程
root@nxbb:/mnt/# ./Semphore 1
touch /tmp/InitSemFlg
m_key=0x00010101.
before getval: 1
ThrdNo=1, P.
c
ThrdNo=1, V.
6.2 运行2号进程
root@nxbb:/mnt# ./Semphore 2
m_key=0x00010101.
before getval: 0
iThrdNo=2, P.
iThrdNo=2, V.