Python检查另一个python应用程序是否正在运行

时间:2014-02-24 16:18:15

标签: python windows multithreading process flock

我有两个应用程序(从python编译,仅在Windows上运行)。第一个是预定的:它启动,启动另一个应用程序的几个实例并死掉。此外,此预定应用程序应检查以前启动的子应用程序实例是否仍在运行。

要实现此检查,我尝试使用文件锁定方法:

  1. 在子应用中创建文件并获取显式锁定。如果是的话 应用程序崩溃锁应该自动释放。
  2. 检查此文件 预定的应用。如果它被锁定 - 这意味着子应用程序仍然是 运行
  3. 这在PERL中很容易实现,但我在python中遇到了一些麻烦。

    我尝试使用win32 API(从portalocker剪切所需的部分代码)。

    以下是测试脚本:

    import os
    import win32con
    import win32file
    import pywintypes
    import sys
    import time
    import threading
    
    def createLockFile(filePath = "c:\\\\test.tmp"):
        file = open(filePath, "a+")
        hfile = win32file._get_osfhandle(file.fileno())
        win32file.LockFileEx(hfile, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, pywintypes.OVERLAPPED())
    
    def lockFile(filePath = "c:\\\\test.tmp"):
        t = threading.Thread(target=createLockFile, args=(filePath,))
        t.start()
    
    def checkFileLock(filePath = "c:\\\\test.tmp"):
        log = open(filePath, "a+")
        #here should be IOError: [Errno 13] in case of error
        print 'File is not locked'
    
    def go():
        print 'start'
        lockFile()
        print 'file locked'
        print 'sleeping'
        time.sleep(30)
        print 'getting up'
    

    我打开两个Python shell实例并导入这个脚本。 然后我在其中一个中启动go()方法,当它处于休眠状态时,我启动checkFileLock()函数来检查文件是否实际被锁定......而事实并非如此。

    我也尝试离开sys.stdin.readline,就像在portalocker中完成一样,在这种情况下文件确实被锁定了。但是没有必要在我的应用程序中听stdin ...

    所以我在创建锁的线程中创建了无限循环。在这种情况下,文件也被锁定,但即使在我关闭Python shell之后它也不会被释放,这也是不正确的。

    我将非常高兴听到如何解决在Windows中从Python锁定文件的问题。 如果您有任何其他工作方法如何确定该过程是否仍在运行,我也希望听到它。

2 个答案:

答案 0 :(得分:2)

我使用代码here来执行此操作。在我的情况下,我总是在Windows中运行,所以我删除了平台检查。它对我有用。

import os, time, sys

class SingleInstance:
    def __init__(self, filename):
        self.lockfile = filename

        try:
            # file already exists, we try to remove (in case previous execution was interrupted)
            if os.path.exists(self.lockfile):
                os.unlink(self.lockfile)

            self.fd =  os.open(self.lockfile, os.O_CREAT|os.O_EXCL|os.O_RDWR)

        except OSError as e:
            if e.errno == 13:
                print("Another instance is already running, quitting.")
                #sys.exit(-1)

            print(e.errno)
            raise

        except Exception as x:
            print(x)

    def __del__(self):
        import sys

        if hasattr(self, 'fd'):
            os.close(self.fd)
            os.unlink(self.lockfile)

答案 1 :(得分:0)

我对Windows不太熟悉,但Linux中的类似情况使用ps来检查应用程序名称。这假定您具有不同的应用程序名称,并且您正在使用这些名称运行它们。

举个例子,这里检查firefox是否已经在运行。

psout = subprocess.Popen(['ps', 'ax'], stdout=subprocess.PIPE).communicate()[0]
if 'firefox' not in psout:
  print 'Firefox has not yet been started'
  subprocess.Popen(['firefox', '-new-tab'])
else:
  print 'Firefox already running'