说明:Linux平台
代码:
/** @file processlock.h
* @brief 进程锁实现
* @date 2015-4-15
* @note 用有名信号量实现
*/
#pragma once
#include <semaphore.h>
using std::string;
class CProcessLock
{
public:
CProcessLock();
~CProcessLock();
bool init(const char *pName);
bool init(const string &name);
void unInit();
void lock();
void unlock();
bool is_good();//锁是否已经创建完成
private:
sem_t *sem_;//信号量id
char sem_name[64];//信号量名字
bool init_;//信号量初始化是否完成
};
#include <unistd.h>
#include <sys/sem.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include "processlock.h"
using std::string;
#define OPEN_FLAG O_RDWR|O_CREAT
#define OPEN_MODE 00777
#define INIT_V 1
CProcessLock::CProcessLock()
{
init_ = false;
memset(sem_name, 0, 64);
}
CProcessLock::~CProcessLock()
{
unInit();
}
bool CProcessLock::init(const char *pName)
{
if(NULL == pName)
return false;
int nLen = strlen(pName);
if(nLen > 64)
{
nLen = 64;
}
memcpy(sem_name, pName, nLen);
sem_ = sem_open(sem_name, OPEN_FLAG, OPEN_MODE, INIT_V);
if(sem_ == SEM_FAILED)
{
printf("create error:%d\n", errno);
return false;
}
else
{
init_ = true;
}
return true;
}
bool CProcessLock::init(const string &name)
{
if(name.empty())
return false;
int nLen = name.length();
if(nLen > 64)
{
nLen = 64;
}
memcpy(sem_name, name.c_str(), nLen);
sem_ = sem_open(name.c_str(), OPEN_FLAG, OPEN_MODE, INIT_V);
if(sem_ == SEM_FAILED)
{
printf("create error:%d\n", errno);
return false;
}
else
{
init_ = true;
}
return true;
}
bool CProcessLock::is_good()
{
return init_;
}
void CProcessLock::unInit()
{
if(init_ && sem_!= NULL)
{
sem_unlink(sem_name);//删除系统中的信号量
sem_close(sem_);//销毁打开的信号量
}
init_ = false;
sem_ = NULL;
memset(sem_name, 0, 64);
}
void CProcessLock::lock()
{
sem_wait(sem_);
}
void CProcessLock::unlock()
{
sem_post(sem_);
}
//测试用例
/**
进程锁测试用例
编译:
加锁:g++ -Wall -g -DUSE_LOCK -lrt -o test_processlock test_processlock.cpp processlock.cpp
不加锁:g++ -Wall -g -lrt -o test_processlock test_processlock.cpp processlock.cpp
*/
#include <cstdio>
#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include "processlock.h"
using namespace std;
CProcessLock mylock;
#define MAX_LEN 1000
void print_log(const char *buf)
{
#ifdef USE_LOCK
mylock.lock();
#endif
for(int i=0; i<MAX_LEN; i++)
{
printf("%c ", buf[i]);
fflush(stdout);
usleep(2000);
}
#ifdef USE_LOCK
mylock.unlock();
#endif
}
int main(int argc, char *argv[])
{
#ifdef USE_LOCK
mylock.init("mylock");
if(!mylock.is_good())
return 0;
#endif
pid_t pid = -1;
int status = -1;
pid = fork();
if(pid == 0)
{
//child process
char buf[MAX_LEN];
int i=0;
for(i=0; i<MAX_LEN-1; i++)
{
buf[i] = 'x';
}
buf[i] = 0;
print_log(buf);
printf("\n");
return 0;
}
//parent process
char buf[MAX_LEN];
int i=0;
for(i=0; i<MAX_LEN-1; i++)
{
buf[i] = 'y';
}
buf[i] = 0;
print_log(buf);
printf("\n");
wait(&status);
#ifdef USE_LOCK
mylock.unInit();
#endif
return 0;
}
运行结果:不加锁时,子进程和父进程的字符交替出现,加锁后能够互斥输出。
参考:
http://blog.chinaunix.net/uid-20940095-id-66101.html
http://blog.csdn.net/ljianhui/article/details/10243617
http://www.oschina.net/code/snippet_237505_8646