(我在这个例子中使用了pyprocessing模块,但是如果你运行python 2.6或者使用multiprocessing backport,用 multiprocessing 替换 processing 应该可以工作)
我目前有一个程序可以侦听 unix 套接字(使用 processing.connection.Listener),接受连接并生成一个处理请求的线程。在某个时刻,我想优雅地退出该过程,但由于 accept() 调用被阻塞,我看不出有什么办法可以很好地取消它。我至少有一种方法可以在这里工作(OS X),设置一个信号处理程序并从另一个线程发出进程信号,如下所示:
import processing
from processing.connection import Listener
import threading
import time
import os
import signal
import socket
import errno
# This is actually called by the connection handler.
def closeme():
time.sleep(1)
print 'Closing socket...'
listener.close()
os.kill(processing.currentProcess().getPid(), signal.SIGPIPE)
oldsig = signal.signal(signal.SIGPIPE, lambda s, f: None)
listener = Listener('/tmp/asdf', 'AF_UNIX')
# This is a thread that handles one already accepted connection, left out for brevity
threading.Thread(target=closeme).start()
print 'Accepting...'
try:
listener.accept()
except socket.error, e:
if e.args[0] != errno.EINTR:
raise
# Cleanup here...
print 'Done...'
我想到的唯一另一种方法是深入连接(listener._listener._socket)并设置非阻塞选项......但这可能有一些副作用并且通常非常可怕。
有没有人有更优雅(甚至可能是正确的!)的方式来完成这个?它需要可移植到 OS X、Linux 和 BSD,但 Windows 可移植性等不是必需的。
澄清:谢谢大家!像往常一样,我原来的问题中的歧义被揭示了:)
- 我需要在取消监听后执行清理,并且我并不总是想真正退出该过程。
- 我需要能够从不是从同一个父进程产生的其他进程访问这个进程,这使得队列变得笨拙
- 线程的原因是:
- 他们访问共享状态。实际上或多或少是一个常见的内存数据库,所以我想它可以做得不同。
- 我必须能够同时接受多个连接,但实际线程大部分时间都在阻塞。每个接受的连接都会产生一个新线程;这是为了不阻止 I/O 操作上的所有客户端。
关于线程与进程,我使用线程来使我的阻塞操作非阻塞,并使用进程来启用多处理。