(Я использую модуль pyprocessing в этом примере, но замена обработки на многопроцессорность, вероятно, будет работать, если вы запустите python 2.6 или используйте многопроцессорный backport)
В настоящее время у меня есть программа, которая прослушивает сокет unix (используя обработчик .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 и т.д. Не требуется.
Разъяснение: Спасибо всем! Как обычно, обнаруживаются двусмысленности в моем первоначальном вопросе:)
- Мне нужно выполнить очистку после того, как я отменил прослушивание, и я не всегда хочу выйти из этого процесса.
- Мне нужно иметь доступ к этому процессу из других процессов, не созданных из одного и того же родителя, что делает Queues неудобными
- Причины для потоков:
- Они получают доступ к общему состоянию. На самом деле более или менее общая база данных в памяти, поэтому я полагаю, что это можно сделать по-другому.
- Я должен иметь возможность одновременного подключения нескольких соединений, но фактические потоки блокируют что-то большую часть времени. Каждое принятое соединение создает новый поток; это, чтобы не блокировать всех клиентов в операциях ввода-вывода.
Что касается потоков против процессов, я использую потоки для того, чтобы блокировать операции блокировки и процессы, чтобы обеспечить многопроцессорность.