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