仿singleten模式的Client-Server方法

在看一个豆瓣FM项目的QT程序。里面用到了类似单例模式(singleten)的客户端-服务器方法,用来控制该程序只能运行一个实例进程。


singleten

所谓的单例模式是指一个类只有一个实例,并提供一个访问它的全局访问点,参见_大话设计模式_ P213。

class Singleton
{
    private:
    Singleton(){}
    static Singleton *instance;
    public:
    static Singleton* GetInstance()
    {
        if(instance == NULL)
        instance = new Singleton();
        return instance;
    }
}

可以看出此类的构造函数为私有,因此不能用new来实例化对象。只能通过静态方法(方法调用独立于对象):

` Singleton *p1 = Singleton :: GetInstance() `


使用QLocalSocket

我们再看一下QT里是采用什么方法。

QLocalSocket socket;//Connect to the local server
socket.connectToServer(LOCAL_SOCKET_NAME);
if (socket.waitForConnected(500)) {
        qWarning() << "There is already a instance running, /
        raising it up";
        return 0;
}

QLocalServer server(&w);
 w.connect(&server, &QLocalServer::newConnection, [&] () {
     if (w.isHidden())
         w.show();
     else
         w.activateWindow();
     qDebug() << "Raise window";
    }
);
server.listen(LOCAL_SOCKET_NAME);

这里,先用QLocalSocket新建连接来连接本地服务器,如果能连上,说明已经存在服务器,即有一个实例进程了。这时退出。

QLocalServer则新建一个服务器,同时监听客户端消息。


读写锁机制

在_APUE_守护进程一节也谈到了当守护进程只有一个副本运行时,我们可以这样做:

每一个守护进程创建一个有固定名字的文件,并在该文件整体上加一把写锁,那么允创建一把这样的写锁。在此之创建写锁的尝试 都会失败,这向后续守进副本指明已有一个副本正在运行。

至于其应用,可以参加A SYSU H3C Client in *NIX

示例如下:

#define LOCKFILE "/var/run/daemon.pid"
#define LOCKMODE (S_IRUSR |S_IWUSR |S_IRGRP |S_IROTH)

//extern int lockfile(int);

int already_running(void)
{
    int fd;
    char buf[16];

    fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
    if(fd < 0){
        syslog(LOG_ERR, "can't open %s: %s", LOCKFILE, strerror(errno));
        exit(1);
    }
    if(lockf(fd, F_TLOCK, 0) < 0){
       // if(errno == EACCES || errno == EAGAIN){
       //     close(fd);
        syslog(LOG_ERR, "can't lock %s: %s", LOCKFILE, strerror(errno));
            return 1;
        }
    ftruncate(fd, 0);//将文件大小置为0
    sprintf(buf, "%ld", (long)getpid());
    write(fd, buf, strlen(buf)+1);
    return 0;
}


Reference

[1].http://www.raychase.net/2556

[2].http://blog.csdn.net/hackbuteer1/article/details/7460019

[3].http://blog.csdn.net/yangxiao_0203/article/details/11492137

[4].APUE. Page380



Previous     Next
/
Published under (CC) BY-NC-SA in categories c&&c++  tagged with