当前位置:  技术问答>linux和unix

有关信号量问题

    来源: 互联网  发布时间:2017-05-22

    本文导语:  #ifndef __LIBAPS_SEMAPHORE_HPP__ #define __LIBAPS_SEMAPHORE_HPP__ #include  #include  namespace aps  {     //! 信号量     class LIBAPS_API Semaphore      {     public:         Semaphore(unsigned int initial = 0, const char* name = 0) throw(Exceptio...


#ifndef __LIBAPS_SEMAPHORE_HPP__
#define __LIBAPS_SEMAPHORE_HPP__

#include 
#include 

namespace aps 
{
    //! 信号量
    class LIBAPS_API Semaphore 
    {
    public:
        Semaphore(unsigned int initial = 0, const char* name = 0) throw(Exception);
        ~Semaphore() throw(Exception);

        void wait() throw(Exception);
        bool tryWait() throw(Exception);
        void post() throw(Exception);

    private:
        struct sem_handle_t;
        sem_handle_t* mHandle;
    };

}

#endif // !__LIBAPS_SEMAPHORE_HPP__

#include 
#include 
#include 
#include 
#include 
#include 

#ifdef Z_OS_LINUX

#include 
#include 
#include 
#include 
#include 

using namespace aps;

struct Semaphore::sem_handle_t 
{
    sem_t* semaphore;
    char* name;
    bool creator;

    sem_handle_t()
    {
        name = NULL;
        semaphore = NULL;
    }
};

Semaphore::Semaphore(unsigned int initial, const char* name) throw(Exception):
mHandle(new sem_handle_t)
{
    if(name)
    {
        sem_t* sem = NULL;
        int flags = O_RDWR | O_CREAT | O_EXCL; //O_CREAT|O_EXCL;
        mHandle->creator = true;

        for (int t = 0; ; t++)
        {
            if (t>0)
                TraceX(eTRACE, _G2U("尝试重新以%d打开信号量%s"), flags, name);
            
            sem = sem_open(name, flags, 0755, initial);
            int r = errno;
            if(sem == SEM_FAILED)
            {
                if(r != EEXIST)
                {
                    logException(Z_SOURCEINFO, r, _G2U("打开信号量%s失败:[%d][%s]"), name, r, Toolkit::formatError(r).c_str());
                }
                else 
                {
                    TraceX(eTRACE, _G2U("信号量%s已存在, 尝试打开"), name);
                    flags = 0;
                    mHandle->creator = false;
                    continue;
                }
            }
            break;
        }
        
        mHandle->semaphore = sem;
        mHandle->name      = strdup(name);
    }
    else
    {
        mHandle->name = 0;
        mHandle->semaphore = new sem_t;

        if(sem_init(mHandle->semaphore, 0, initial) == -1)
        {
            int r = errno;
            logException(Z_SOURCEINFO, r, _G2U("sem_init失败: %s"), Toolkit::formatError(r).c_str());
        }
    }
}

Semaphore::~Semaphore() throw(Exception)
{
    if(mHandle->name)
    {
        if(sem_close(mHandle->semaphore) == -1)
            Trace(eERROR, _G2U("无法关闭信号量(%s): %s"), mHandle->name, Toolkit::formatError(errno).c_str());
        else 
            TraceX(eTRACE, _G2U("sem_close(%s)成功"), mHandle->name);

        // 删除
        if(mHandle->creator)
        {
            if(sem_unlink(mHandle->name) == -1)
                Trace(eERROR, _G2U("无法删除信号量(%s): %s"), mHandle->name, Toolkit::formatError(errno).c_str());
            else
                TraceX(eTRACE, _G2U("sem_unlink(%s)成功"), mHandle->name);
        }

        free(mHandle->name);
    }
    else
    {
        if(sem_destroy(mHandle->semaphore) == -1)
        {
            int r = errno;
            Trace(eERROR, _G2U("sem_destroy失败: %s"), Toolkit::formatError(r).c_str());
        }
        delete mHandle->semaphore;
    }

    delete mHandle;
}

void Semaphore::wait() throw(Exception)
{
    sem_wait(mHandle->semaphore);
}

bool Semaphore::tryWait() throw(Exception)
{
    return (sem_trywait(mHandle->semaphore) == 0) ? true : false;
}

void Semaphore::post() throw(Exception)
{
_sempost_posix:
    if(sem_post(mHandle->semaphore) == -1)
    {
        int r = errno;
        if(r == EINTR)
            goto _sempost_posix;

        throw Exception(Z_SOURCEINFO, r, _G2U("无法增加信号量"));
    }
}

#endif

Semaphore t(1, "UpdPkgAssist.lock");


在生产上会遇到一天几百次,上千次创建后,偶尔会出现
sem = sem_open(name, O_RDWR | O_CREAT | O_EXCL, 0755, initial);
判断存在,然后用
sem_open(name, 0, 0755, initial);又报不存在的情况
想问下大家可能是什么原因?

|
在生产上会遇到一天几百次,上千次创建后,偶尔会出现
sem = sem_open(name, O_RDWR | O_CREAT | O_EXCL, 0755, initial);
判断存在,然后用
sem_open(name, 0, 0755, initial);又报不存在的情况
想问下大家可能是什么原因? 
========
在两次sem_open之间有其他进程删除了信号量吧

|


看下这个: 
http://www.cnblogs.com/BloodAndBone/archive/2011/01/18/1938552.html
如果指定了O_CREAT(而没有指定O_EXCL),那么只有所需的信号灯尚未存在时才初始化他。所需信号灯已存在条件下指定O_CREAT不是个错 误。该标志的意思仅仅是“如果所需信号灯尚未存在,那就创建并初始化他”。不过所需信号灯等已存在条件下指定O_CREAT|O_EXCL却是个错误。

你的程序存不存在多线程?

|

很有可能多个进程对同一个sem操作

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • 求教有关smartupload的问题,有关就给分!!
  • 有关在sco unix5.0.4下有关网卡设置的问题(非常急,高分相送)
  • 有关snmp的一个很菜,但是困扰了我很久的问题,有关工作原理的,望大家赐教
  • 有关ResultSet的问题,帮助解决问题者另外加分...
  • (菜鸟问题)有关目录中文件执行的问题???
  • 有关Qt下编译的环境问题
  • 有关裁减内核及shell命令的问题
  • 有关cocoon的问题??
  • Helper! 有关Jbuilder使用问题???
  • 有关swing的问题,请高手回答
  • 一个有关分数的问题
  • 有关pcmaclan的打印机共享问题
  • 请教有关samba共享名大小写的问题
  • 想看一下吗?有关swing 组件的问题?
  • 有关L的问题(菜鸟求教)???
  • 有关jsp服务器的一个问题
  • java 进阶级问题,有关网络的问题,请多多帮助
  • 有关Liunx 的最低配置问题
  • 有关环境的问题
  • 请教有关konqueror 问题?
  • ​有关Docker的八个令人难以置信的事实
  • 有关内码转换(跟HttpServletRequest有关)
  • 求有关png图像处理的libpng库的有关中文资料
  • 大家推荐一下有关LINUX7有关的网络编程的书。最好是比较全面的!比较经典的。
  • 有关KDevelop-3.0.4-0.1.i386.rpm的有关软件包
  • 有关KDevelop编程的资料
  • 有关集群与数据同步
  • 请教有关英文简历方面的词句!
  • 有关报表打印(在JAVA,WEB下应用)急用!
  • 请各位大哥告知JAVA中消息机制的有关资料,拜托!
  • 有关jbuilder


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,