Скрученный Python с callInThread - PullRequest
       16

Скрученный Python с callInThread

3 голосов
/ 02 ноября 2010

Я разобрал свое приложение, но это должно дать вам пример того, что я делаю

def run_app(f):
    p = Popen(['/usr/bin/app'],stdout=PIPE)
    while True:
        o = p.stdout.readline()
        if o == '' and p.poll() != None: break

        reactor.callFromThread(f, o)

class Echo(Protocol):
    def connectionMade(self):

        reactor.callInThread(run_app, self.appDataReceived)

    def dataReceived(self, data):
        data = data.strip()
        if data == "getmore":
            print "getmore"

    def appDataReceived(self, u):
        print u

def main():
    factory = Factory()
    factory.protocol = Echo
    reactor.listenTCP(3646, factory)
    reactor.run()

if __name__ == "__main__":
    main()

У меня есть приложение, к которому я хочу подключиться и запустить приложение, которое постоянно выплевывает данные на стандартный вывод. Сейчас мое приложение работает, но проблема в том, что когда клиент выходит из сокетного соединения, приложение / usr / bin / app продолжает работать. Чем больше подключений к сокетам, тем больше работает это приложение.

Есть ли в Echo Procool возможность убить функцию run_app ()?

Ответы [ 2 ]

3 голосов
/ 03 ноября 2010

Не используйте темы и попен. Используйте Поддержка процесса Twisted . Кроме того, ваш Echo протокол нуждается в кадрировании , иначе нет гарантии, что он когда-либо получит строку "getmore".

1 голос
/ 02 ноября 2010

Есть несколько предложений, которые я могу сделать, и, надеюсь, это решит ваши проблемы.

Не используйте реактор.callFromThread, вместо этого используйте deferToThread

from twisted.internet.threads import deferToThread
deferredObj = threads.deferToThread(run_app, self.appDataReceived)

Точно так же, как вы запускаете поток, когда соединение установлено. Вы должны действовать, когда соединение потеряно.

Пример кода:

class Echo(Protocol):
    def connectionLost(self, reason):
        print reason
        # which is crude, there should be a more elegant answer
        reactor.stop() 

Согласился, что deferToThread оптимизирован для краткосрочных задач. На самом деле, лучше сделать код заново, чтобы вы могли вызвать поток, чтобы просто запустить процесс и вернуть результат.

...