2

我确定这个问题之前已经被问过,但我找不到它。

我编写了一个 Python 程序,给定一个目录,它使用一个非常简单的启发式方法来确定如何“解包”它的内容以及目标目录。

每当完成新的下载时,就会执行该程序。如果大量下载几乎同时完成,我会得到很多进程同时解压东西。我想通过重写大部分程序来解决这个问题,一次只解压一个目录。

所以为了实现这一点,我想我会使用一个“lock/PID”文件,其中包含任何当前正在执行的程序的 PID。如果锁/PID 文件存在,新生成的进程应该简单地向("queue", "D:/some/directory")现有进程发送一些内容,并让该进程在完成当前解包后解包该目标。

我将如何在 Python 中实现这一点?这必须在 Windows 系统上工作,但在 GNU/Linux 上也是理想的。

4

2 回答 2

0

如果只想检查PID文件是否存在,可以使用:os.path

os.path.exists(path) 
于 2012-04-11T08:24:55.007 回答
0

因此,既然您已经在使用Ben Finney 的 lockfile之类的东西

例子:

 from lockfile.pidlockfile import PIDLockFile
 lock = PIDLockFile('somefile')
 lock.acquire(timeout=3600)
 #do stuff
 lock.release()

您可能希望与正在运行的守护程序通信,您应该让守护程序侦听某个套接字,然后从生成的进程向套接字发送数据。(例如 udp 套接字)

所以在守护进程中:

import socket
import traceback
import Queue
import threading
import sys

hostname = 'localhost'
port = 12368
#your lockfile magick here
# if you want one script to run each time, put client code here instead of seperate script
#if already running somehwere:
    #message = "hello"
    #sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
    #sock.sendto( message, (hostname, port) )
    #sys.exit(0)

que = Queue.Queue(0)

socket_ = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
socket_.bind((hostname, port))

class MyThread(threading.Thread):
    def run(self):
        while True: #maybe add some timeout here, so this process closes after a while
                    # but only stop if que.empty()
            message = que.get()
            print "handling message: %s" % message
            #handle message

t = MyThread()
t.start()

while True:
        try:
            #blocking call
            message, _ = socket_.recvfrom(8192) #buffer size
            print "received message: %s"  % message
            #queue message
            que.put(message)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            traceback.print_exc()

在客户端:

import socket
hostname = 'localhost'
port = 12368
message = "hello"
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
sock.sendto( message, (hostname, port) )

如果您在同一台机器上运行所有这些,则可以使用“localhost”作为主机名。

另一方面,使用多进程管道而不是套接字可能是正确的方法,但我还没有这方面的经验。此设置的额外好处是能够在不同的机器上运行服务器和客户端。

于 2012-04-11T08:52:05.823 回答