Как поставить tcp сервер на другой поток в python - PullRequest
2 голосов
/ 05 ноября 2011

Я пытаюсь написать демон на python. Но я понятия не имею, как я могу использовать поток для запуска параллельного tcp-сервера в этом демоне. И даже какой тип сервера я должен использовать: asyncore? SocketServer? Сокет?

это часть моего кода:

import os
def demonized():
   child_pid = os.fork()
   if child_pid == 0:
       child_pid = os.fork()
       if child_pid == 0:          #fork twice for demonize
           file = open('###', "r") # open file
           event = file.read()
           while event:
               #TODO check for changes put changes in list variable
               event = file.read()
       file.close()
       else:
           sys.exit(0)
   else:
       sys.exit(0)


if __name__ == "__main__":
  demonized()

Итак, в цикле у меня есть переменная списка с некоторыми данными, добавляемыми в каждом круге, и я хочу запустить поток с tcp-сервером, который ожидает подключения в цикле и, если клиент подключается, отправляет ему эти данные (с нулевой переменной). Поэтому мне не нужно обрабатывать несколько клиентов, клиент будет только один за раз. Каков оптимальный способ реализовать это?

Спасибо.

Ответы [ 2 ]

5 голосов
/ 05 ноября 2011

Если вы не хотите повторять шаблон, у Python скоро появится стандартный модуль, который выполняет пару fork() и стандартные операции ввода-вывода (которые вы еще не добавили в свою программу?), Что делает его демоном , Вы можете скачать и использовать этот модуль прямо сейчас, с:

http://pypi.python.org/pypi/python-daemon

Запуск TCP-сервера в отдельном потоке часто так прост:

import threading

def my_tcp_server():
    sock = socket.socket(...)
    sock.bind(...)
    sock.listen()
    while True:
        conn, address = sock.accept()
        ...
        ... talk on the connection ...
        ...
        conn.close()

def main():
    ...
    threading.Thread(target=my_tcp_server).start()
    ...

Я настоятельно рекомендую против пытаться заставить ваш поток чтения файлов и ваш поток ответа на сокеты говорить со списком и блокировкой вашего собственного устройства; такие схемы трудно заставить работать и трудно продолжать работать. Вместо этого используйте класс Queue.Queue() стандартной библиотеки, который выполняет все блокировки и добавления правильно для вас.

0 голосов
/ 05 ноября 2011

Хотите добавить элементы в список в цикле while event:... и одновременно обслуживать этот список? Если так, то у вас есть два автора, и вы должны каким-то образом защитить свой список.

В выборке SocketServer.TCPServer и threading.Lock использовалось:

import threading
import SocketServer
import time


class DataHandler(SocketServer.StreamRequestHandler):

    def handle(self):
        self.server.list_block.acquire()
        self.wfile.write(', '.join(self.server.data))
        self.wfile.flush()
        self.server.data = []
        self.server.list_block.release()


if __name__ == '__main__':
    data = []
    list_block = threading.Lock()

    server = SocketServer.TCPServer(('localhost', 0), DataHandler)
    server.list_block = list_block
    server.data = data

    t = threading.Thread(target=server.serve_forever)
    t.start()

    while True:
        list_block.acquire()
        data.append(1)
        list_block.release()
        time.sleep(1)
...