C++编写单实例运行的程序

有些程序要求只运行一个实例, 实现单实例的方法也有多种, 之前我一般是通过锁住一个pid文件实现单实例运行, 最近在网上看到绑定套接字的方法实现单实例运行,这种方法在程序退出时候能够自动释放套接字, 实现了自我清理的过程, 很是优雅。

//singleton.h

#include <iostream>
#include <string>

class Singleton
{
public:
Singleton(uint16_t port) : socket_fd_(-1), rc_(1), port_(port)
{}

~Singleton();

bool operator()();

private:
int socket_fd_ = -1;
int rc_;
uint16_t port_;
};
//singleton.cpp

#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include "singleton.h"

Singleton::~Singleton()
{
if (socket_fd_ != -1)
{
close(socket_fd_);
}
}

bool Singleton::operator()()
{
if (socket_fd_ == -1 || rc_)
{
socket_fd_ = -1;
rc_ = 1;

if ((socket_fd_ = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
throw std::runtime_error(std::string("could not create socket: ") + strerror(errno));
} else
{
struct sockaddr_in name;
name.sin_family = AF_INET;
name.sin_port = htons(port_);
name.sin_addr.s_addr = htonl(INADDR_ANY);
rc_ = bind(socket_fd_, (struct sockaddr *) &name, sizeof(name));
}
}

return (socket_fd_ != -1 && rc_ == 0);
}
//main.cpp

#include <iostream>
#include "singleton.h"

int main(int argc, char *argv[])
{
const int port = 5678;
Singleton single(port);

if (!single())
{
std::cerr << "program already running." << std::endl;
exit(-1);
}

while (true)
{
// keep program do not return
;
}

return 0;
}