第二人生的源码分析(七十六)判断程序运行多个实例
随着多任务系统的流行,可以轻易地把同一个程序同时运行多个实例,这对于一般的应用程序来说,是非常有用的,也大大地提高电脑的使用率。但是对于像第二人生这样的游戏来说,运行多个实例,是不需要的,也是不现实的。因为它需要非常多的CPU计算,独占CPU还不够用,别说运行多个实例了,并且它是全屏运行的游戏,多个程序运行也不必要。那么第二人生里是使用什么方法来实现跨平台的多个实例运行的检测呢?下面就来看看这段代码:
#001 bool LLAppViewer::anotherInstanceRunning()
#002 {
#003 // We create a marker file when the program starts and remove the file when it finishes.
#004 // If the file is currently locked, that means another process is already running.
#005
获取作标记文件的路径和名称。
#006 std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, MARKER_FILE_NAME);
#007 llinfos << "Checking marker file for lock..." << llendl;
#008
用只读的方式打开文件。
#009 //Freeze case checks
#010 apr_file_t* fMarker = ll_apr_file_open(marker_file, LL_APR_RB);
打开文件成功,说明已经存在这个文件,如果不存在文件,肯定就不存在多个实例了。
#011 if (fMarker != NULL)
#012 {
说明文件已经存在,先把只读方式的文件关闭。
#013 // File exists, try opening with write permissions
#014 apr_file_close(fMarker);
用写的方式打开这人文件。
#015 fMarker = ll_apr_file_open(marker_file, LL_APR_WB);
如果这样打开文件不成功,说明已经有一个实例已经运行,因为前一个实例用只写的方式打开文件的。
#016 if (fMarker == NULL)
#017 {
#018 // Another instance is running. Skip the rest of these operations.
#019 llinfos << "Marker file is locked." << llendl;
打开文件不成功,说明已经有一个实例运行。
#020 return TRUE;
#021 }
下面锁住这个文件,不允许再用写的方式打开。
#022 if (apr_file_lock(fMarker, APR_FLOCK_NONBLOCK | APR_FLOCK_EXCLUSIVE) != APR_SUCCESS) //flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1)
#023 {
#024 apr_file_close(fMarker);
#025 llinfos << "Marker file is locked." << llendl;
#026 return TRUE;
#027 }
#028 // No other instances; we'll lock this file now & delete on quit.
用写的方式能打开文件,说明没有另外的实例运行。
#029 apr_file_close(fMarker);
#030 }
#031 llinfos << "Marker file isn't locked." << llendl;
#032 return FALSE;
#033 }
上面这段代码是通过使用一个不共享写文件的方法来判断是否已经存在另外一个实例,这就是第二人生跨平台检测是否有第二个实例运行的方法。