2013-08-16 1 views
0

У меня есть мой сервер python baseHTTPServer, который обрабатывает почтовые запросы. Я использовал ThreadingMixIn, и теперь он открывает поток для каждого соединения. Я хочу выполнить несколько многопоточных действий, таких как: 1. Мониторинг успешных/неудачных действий подключения, добавив 1 к счетчику для каждого. Мне нужен замок для этого. Мой счетчик находится в глобальном масштабе того же файла. Как я могу это сделать? 2. Я хочу обрабатывать какую-то очередь и записывать ее в файл, где содержимое очереди представляет собой набор строк, написанных из разных потоков, который просто отправляет некоторую информацию для проблем с протоколированием. Как это можно сделать? Я не могу этого сделать, поскольку моя потоковая обработка выполняется «за кадром», так как каждый раз Im в do_POST (..) метод, Im уже в другом потоке.Поддержание файла журнала из нескольких потоков в Python

Succcessful_Logins = 0 
Failed_Logins = 0 
LogsFile = open(logfile) 

class httpHandler(BaseHTTPRequestHandler): 

    def do_POST(self): 
     .. 

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer): 
    pass 

server = ThreadingHTTPServer(('localhost', PORT_NUMBER), httpHandler) 
server.serve_forever() 

Это небольшой хрупкий мой сервер. Еще одна вещь, которая беспокоит меня - это лицо, с которым я хочу сначала отправить ответ отклика обратно клиенту, и только после этого возможно получить задержку из-за механизма блокировки или чего-то еще.

ответ

0

С вашего кода, похоже, что новый HTTPHandler построен в каждом потоке? Если это так, вы можете использовать переменный класс для подсчета и мьютекс для защиты счета, как:

class httpHandler(...): 
    # Note that these are class variables and are therefore accessable 
    # to all instances 
    numSuccess = 0 
    numSuccessLock = new threading.Lock() 

    def do_POST(self): 
     self.numSuccessLock.aquire() 
     self.numSuccess += 1 
     self.numSuccessLock.release() 

Что касается записи в файл из разных потоков, есть несколько вариантов:

  1. Используйте модуль протоколирования: «Модуль протоколирования предназначен для потоковой защиты без какой-либо специальной работы, которая должна выполняться его клиентами». от http://docs.python.org/2/library/logging.html#thread-safety
  2. Используйте объект блокировки, как и выше сериализовать записи в файл
  3. Используйте нить безопасных очереди в очереди операций записи, а затем считывается из очереди и записи в файл из отдельного потока. См. Примеры http://docs.python.org/2/library/queue.html#module-Queue.
+0

Но если numSuccess является переменной класса, он создается снова и снова для каждого нового соединения (= поток), я ошибаюсь? О блокировке мьютекса, могу ли я обработать его после того, как я вернусь с моего do_POST, чтобы не откладывать ответ? – buddy123

+0

* Экземпляры * переменные для каждого экземпляра, а переменные * class * - для каждого класса. Таким образом, numSuccess создается только один раз для всей программы. [это сообщение в блоге] (http://timothyawiseman.wordpress.com/2012/10/06/class-and-instance-variables-in-python-2-7/) содержит более подробную информацию. Я не знаю, можете ли вы отложить его до тех пор, пока do_POST, потому что я не знаю, как выглядит остальная часть вашего кода. Однако время, необходимое для блокировки и увеличения, должно быть минимальным, поэтому я не думаю, что вы заметите задержку. –

+0

Хорошо. Спасибо, Оливер. Я прочитаю о ссылке, которую вы поделили с модулем протоколирования. во всяком случае, есть небольшое исправление, которое вам нужно сделать. В ответе, который вы мне предоставили, переменные должны быть доступны с помощью имени класса 'httpHandler', а не' self' – buddy123

Смежные вопросы