一个跨平台的单列Singletonlnst的实现
来源:互联网 发布:红黑树java实现 编辑:程序博客网 时间:2024/04/29 22:30
#if !defined(SINGLEONINST_H_)
#define SINGLEONINST_H_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "hstring.h"
//////////////////////////////////////////////////////////////////////////
// CSingletonInst
class CSingletonInst
{
// Constructions
public:
CSingletonInst(LPCSTR lpszInstName);
~CSingletonInst();
private:
CSingletonInst();
CSingletonInst(const CSingletonInst &);
CSingletonInst & operator = (const CSingletonInst &);
// Operations
public:
BOOL TryRun(CHString &strErr);
// Member
private:
char m_szInstName[512];
#ifdef WIN32
HANDLE m_hMutex;
#endif
};
#endif // SINGLEONINST_H_
---------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// CSingletonInst
CSingletonInst::CSingletonInst(LPCSTR lpszInstName)
{
COM_ASSERT(NULL != lpszInstName);
SAFE_STRCPY(m_szInstName, lpszInstName);
#ifdef WIN32
m_hMutex = NULL;
#endif
}
CSingletonInst::~CSingletonInst()
{
#ifdef WIN32
if (NULL != m_hMutex)
{
::CloseHandle(m_hMutex); //lint !e534 ignored the return value, not care
m_hMutex = NULL;
}
#endif
}
BOOL CSingletonInst::TryRun(CHString &strErr)
{
strErr = "";
#ifdef WIN32
//////////////////////////////////////////////////////////////////////////
// WIN32 implementation start
CHString strMutexName = m_szInstName;
strMutexName += "SINGLETON_INST";
strMutexName.MakeUpper();
m_hMutex = ::CreateMutex(NULL, TRUE, strMutexName);
if (NULL != m_hMutex)
{
if (ERROR_ALREADY_EXISTS == GetLastError())
{
strErr = "another instance running";
return FALSE;
}
}
return TRUE;
// WIN32 implementation end
//////////////////////////////////////////////////////////////////////////
#else // !WIN32
//////////////////////////////////////////////////////////////////////////
// !WIN32 implementation start
CHString strInstFile;
strInstFile.Format("%s/.%s_pidfile",
(LPCTSTR)GetBinPath(),
(LPCTSTR)m_szInstName
);
int fd = open(strInstFile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (fd < 0)
{
strErr.Format("open pid file failed. file=%s.",
(LPCSTR)strInstFile
);
return FALSE;
}
// File record locking structure used by fcntl()
struct flock flk;
flk.l_type = F_WRLCK; // F_RDLCK, F_WRLCK, or F_UNLCK
flk.l_whence = SEEK_SET; // SEEK_SET, SEEK_CUR, SEEK_END
flk.l_start = 0; // starting offset relative to l_whence
flk.l_len = 0; // len == 0 means "until end of file
flk.l_pid = getpid(); // Process ID of the process holding the lock, returned with F_GETLK
if (fcntl(fd, F_SETLK, &flk) < 0)
{
if ((EAGAIN == errno)
|| (EACCES == errno)
)
{
strErr = "another instance running";
}
else
{
strErr.Format("lock pid file failed. file=%s",
(LPCTSTR)strInstFile
);
}
return FALSE;
}
// write pid to file
ftruncate(fd, 0);
char szpid[48] = {0};
sprintf(szpid, "%u", getpid());
write(fd, szpid, strlen(szpid));
return TRUE;
// !WIN32 implementation end
//////////////////////////////////////////////////////////////////////////
#endif // !WIN32
}
//lint -restore
备注:在wondows下是通过互斥量来实现的。
linux下是通过对文件加锁。当另一个相同的进程启动时,获取锁失败。
通过获得失败标志。进而进行退出处理(这部分在这里没有写出来)。
在这里提供一种思路。
- 一个跨平台的单列Singletonlnst的实现
- iOS单列的实现
- 单列的实现的问题
- 返回单列的RowMapper实现
- 实现python的单列模式
- 单列设计模式的实现
- ActionScript3单列模式的一种实现
- 基于c++的单列模式实现。
- 单列数据库索引的实现原理
- 单列模式的多种实现方式
- 一个统计平台的实现
- 单列集合的体系
- 单列的演练
- 简单的单列模式
- php中对象克隆和一个简单的单列类
- php类的静态单列模式的实现方法
- RecyclerView的多条目和单列双列的实现
- LINQ - DISTINCT 单列和多列两种情况下的实现
- DBMS 的个人理解
- shell 脚本中$$,$#,$?分别代表什么意思?
- 计算机网络学习--tcp学习
- .bash_profile和.bashrc的区别(如何设置生效)
- 国外的一些测试技术网站
- 一个跨平台的单列Singletonlnst的实现
- uva 10029 - Edit Step Ladders
- 对Spring的理解
- 环形缓冲区
- Python线程指南<转>
- 成为优秀程序员的十个有效方法
- 编程之美--3.9 重建二叉树
- Struts优缺点
- 手动关联与自动关联