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

问题描述 投票:0回答:3

我有两个应用程序(从 python 编译,仅在 Windows 上运行)。第一个是预定的:它启动,启动另一个应用程序的多个实例,然后终止。此外,此计划应用程序应检查先前启动的子应用程序实例是否仍在运行。

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

  1. 在子应用程序中创建文件并对其进行显式锁定。万一如果 应用程序崩溃锁应该自动释放。
  2. 检查此文件 预定的应用程序。如果它被锁定 - 这意味着子应用程序仍然 跑步。

这在 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() 函数来检查文件是否确实被锁定......但事实并非如此。

我还尝试像在 Portalocker 中一样保留 sys.stdin.readline ,在这种情况下,文件确实被锁定。但我的应用程序中不需要监听 stdin...

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

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

python windows multithreading process flock
3个回答
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)

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'

0
投票

互斥体(互斥的缩写)是一种同步原语,可用于确保对共享资源的独占访问。在这种情况下,它用于确保对您的应用程序的独占访问。

我的代码片段为您的应用程序创建了一个具有唯一标识符的命名互斥体。如果它检测到应用程序的另一个实例已经在运行(通过检查创建互斥体时生成的错误代码),它会打印一条消息并强制退出新实例,从而防止同一应用程序的多个实例同时运行。

import os
import win32event
import win32api
import winerror

APP_IDENTIFIER='dunggramer'

# Create a named mutex using the app identifier
mutex = win32event.CreateMutex(None, 1, APP_IDENTIFIER)

if win32api.GetLastError() == winerror.ERROR_ALREADY_EXISTS:
    print("Another instance of the application is already running.")
    os._exit(0)

# Main your code

# exit app
# Release the mutex when your application is done
win32api.CloseHandle(mutex)
© www.soinside.com 2019 - 2024. All rights reserved.