Я пытаюсь реализовать службу с витыми, что довольно близко к «палец» Tutorial здесь: http://twistedmatrix.com/documents/current/core/howto/tutorial/intro.htmlскрученная резьба с подпроцессом.Popen?
У меня есть basic.LineListener ожидания команды, а затем его выполнения, то у меня есть клиентские соединения и выдача команд. Проблема в том, что команде иногда нужно выполнить что-то еще, и для этого я использую модуль подпроцесса python. Дело не только в том, что звонки на общение() висят, это обычная проблема с подпроцессом, и я знаю, как пройти мимо нее. Это то, что подпроцессы.
Вот скрученный код сервера:
from twisted.application import internet, service
from twisted.internet import protocol, reactor, defer, threads
from twisted.protocols import basic
import sys
import time
import subprocess
class MyProtocol(basic.LineReceiver):
def lineReceived(self, line):
self.go()
def go(self):
def writeResponse(message):
self.transport.write(message + '\r\n')
self.transport.loseConnection()
threads.deferToThread(self.factory.action).addCallback(writeResponse)
def connectionMade(self):
self.lines = []
class ActionService(service.Service):
def __init__(self, **kwargs):
pass
#self.users = kwargs
def action(self):
print "launching subprocess"
sys.stdout.flush()
p = subprocess.Popen(["ls"], stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
print "launched subprocess, trying to communicate..."
sys.stdout.flush()
p.communicate()
print "returning"
sys.stdout.flush()
return "%032d" % (0)
def getActionFactory(self):
f = protocol.ServerFactory()
f.protocol = MyProtocol
f.action = self.action
return f
reactor.suggestThreadPoolSize(300)
application = service.Application('Action', uid=0, gid=0)
f = ActionService()
serviceCollection = service.IServiceCollection(application)
internet.TCPServer(31337,f.getActionFactory()
).setServiceParent(serviceCollection)
... и вот некоторый код клиента:
#!/usr/bin/python
import time
import threading
import socket
def connectAction(host):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, 31337))
s.send("asdf\r\n")
resp = s.recv(32)
s.close()
return resp
class sscceThread(threading.Thread):
def __init__(self, host):
self.host = host
threading.Thread.__init__(self)
def run(self):
connectAction(self.host)
def main():
threads = []
for i in range(0, 1000):
for j in range(0,5):
t = sscceThread("localhost")
t.start()
threads.append(t)
for t in threads:
t.join()
print i
time.sleep(1)
# print i
if __name__ == "__main__":
main()
Запустите службу, запустив:
twistd -y sscce_twisted_service.py -l twistdLog; tail -f twistdLog
И запустить клиент от эксплуатации:
./sscce_twisted_client.py
Вы должны увидеть, что клиент отправился на пару итераций (я видел, что он прошел целых 10), а затем зависает. Клиентский код содержит 1-секундный сон, так что вы можете сказать разницу между витыми записями журнала от каждой итерации и на ту, который нависает вы увидите что-то подобное в скрученном журнале:
2009-12-22 11:18:47-0800 [MyProtocol,55,127.0.0.1] launching subprocess
2009-12-22 11:18:47-0800 [MyProtocol,56,127.0.0.1] launching subprocess
2009-12-22 11:18:47-0800 [MyProtocol,55,127.0.0.1] launched subprocess, trying to communicate...
2009-12-22 11:18:47-0800 [MyProtocol,57,127.0.0.1] launching subprocess
2009-12-22 11:18:47-0800 [MyProtocol,58,127.0.0.1] launching subprocess
2009-12-22 11:18:47-0800 [MyProtocol,56,127.0.0.1] launched subprocess, trying to communicate...
2009-12-22 11:18:47-0800 [MyProtocol,55,127.0.0.1] returning
2009-12-22 11:18:47-0800 [MyProtocol,57,127.0.0.1] launching subprocess
2009-12-22 11:18:47-0800 [MyProtocol,56,127.0.0.1] launching subprocess returning
2009-12-22 11:18:47-0800 [MyProtocol,59,127.0.0.1] launching subprocess
2009-12-22 11:18:47-0800 [MyProtocol,58,127.0.0.1] launched subprocess, trying to communicate...
2009-12-22 11:18:47-0800 [MyProtocol,58,127.0.0.1] returning
2009-12-22 11:18:47-0800 [MyProtocol,59,127.0.0.1] launched subprocess, trying to communicate...
2009-12-22 11:18:47-0800 [MyProtocol,59,127.0.0.1] returning
Особых примечание: MyProtocol, 57. В нем говорится, что он собирается попробовать запустить подпроцесс, но никогда не печатал строку «запущенный подпроцесс, пытающийся связаться». Я думаю, он, должно быть, повесился там.
все кажется прекрасным здесь. PS. используйте 'reactor.spawnProcess' вместо' subprocess' –
Вы хотите принять ответ? –