当前位置:  开发笔记 > 编程语言 > 正文

如何阻止运行同一程序的两个实例?

如何解决《如何阻止运行同一程序的两个实例?》经验,为你挑选了2个好方法。

我需要确保用户一次只能运行我的程序的一个实例.
这意味着,我必须以编程方式检查相同的程序是否已在运行,并在这种情况下退出.

我想到的第一件事就是在程序启动时在某处创建一个文件.然后,程序的每个其他实例将检查此文件并在找到它时退出.
问题是,程序必须始终正常退出并能够删除它创建的文件,以便工作.如果停电,则锁定文件仍然存在,程序无法再次启动.

为了解决这个问题,我决定将第一个程序的进程ID存储到锁定文件中,当另一个实例启动时,它会检查文件中的PID是否附加到某个正在运行的进程.
如果文件不存在,为空,或者PID与任何现有进程不对应,程序将继续运行并将自己的PID写入文件.

这似乎工作得很好 - 即使在意外关闭之后,(现在过时的)进程ID与其他程序相关联的可能性似乎也很低.

但它仍然感觉不对(有由一些不相关的进程被锁的机会),并与进程ID的工作似乎超越C++标准,可能不是非常便携无论是.

那么,还有另一种(更干净,更安全)的方式吗?理想情况下,它可以与ISO 98 C++标准一起使用,也适用于Windows和*nix.
如果它无法独立于平台,Linux/Unix对我来说是一个优先事项.



1> Brian R. Bon..:

您可以使用多种方法来完成仅允许应用程序的一个实例:

方法1:全局同步对象或内存

通常通过创建命名的全局互斥或事件来完成.如果已经创建,那么您知道该程序已在运行.

例如在Windows中你可以这样做:

    #define APPLICATION_INSTANCE_MUTEX_NAME "{BA49C45E-B29A-4359-A07C-51B65B5571AD}"

    //Make sure at most one instance of the tool is running
    HANDLE hMutexOneInstance(::CreateMutex( NULL, TRUE, APPLICATION_INSTANCE_MUTEX_NAME));
    bool bAlreadyRunning((::GetLastError() == ERROR_ALREADY_EXISTS));
    if (hMutexOneInstance == NULL || bAlreadyRunning)
    {
        if(hMutexOneInstance)
        {
            ::ReleaseMutex(hMutexOneInstance);
            ::CloseHandle(hMutexOneInstance);
        }
        throw std::exception("The application is already running");
    }

方法2:锁定文件,第二个程序无法打开文件,因此它是打开的

您也可以通过在应用程序打开时将其锁定来专门打开文件.如果文件已经独占打开,并且您的应用程序无法接收文件句柄,则表示该程序已在运行.在Windows上,您不会FILE_SHARE_WRITE在使用CreateFileAPI 打开的文件上指定共享标志.在linux上你会使用flock.

方法3:搜索进程名称:

您可以枚举活动进程并搜索具有进程名称的进程.


如果两个人复制您的代码,他们可能会以相同的APPLICATION_INSTANCE_MUTEX_NAME结尾:->

2> Greg Hewgill..:

将进程pid写入文件的方法是在许多不同的已建立应用程序中使用的常见方法.事实上,如果你/var/run现在查看你的目录我打赌你会找到几个*.pid文件.

正如你所说,它不是100%强大,因为有可能混淆pids.我听说过flock()用于锁定特定于应用程序的文件的程序,当进程退出时,该文件将由操作系统自动解锁,但此方法更具有特定于平台且不太透明.

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有