进程锁实现-有名信号量

说明: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



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值