当前位置: 技术问答>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之间有其他进程删除了信号量吧
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操作