0
点赞
收藏
分享

微信扫一扫

Linux IPC 信号量


1. 概念原理

​​ipc信号原理​​

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.

 

举报

相关推荐

0 条评论