我試圖實現與扭曲的一種服務,是相當接近的「手指」教程這裏找到:http://twistedmatrix.com/documents/current/core/howto/tutorial/intro.html扭曲的線程與子進程.Popen?
我有一個basic.LineListener等待命令,然後執行它,那麼我有一個客戶端連接和發佈命令。麻煩的是,該命令有時需要執行其他的東西,我正在使用python的子進程模塊。這不僅僅是溝通()的呼叫掛起,這是一個正常的子進程問題,我知道如何克服它。就是那個子進程.Popen調用是掛起的。
這裏是扭曲的服務器代碼:
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
並運行客戶機通過運行:
你應該看到客戶端進行了幾次迭代(我已經看到它多達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' –
你想接受答案嗎? –