Как реализовать потоковый socket.recv () в python? - PullRequest
1 голос
/ 23 апреля 2011

У меня есть несколько устройств, с которых мне нужно получать обновления статуса.Объект сокета - это все, что у меня есть, а socket.recv () - это все, что мне нужно для получения статуса.Помещенные в однопоточное приложение, проблем не возникает:

class Device:
    def receive(self):
        log.debug("receive waiting: %r", self.device_id)
        try:
            packet = self.socket.recv(255)
        except Exception as e:
            self.report_socket_error(e)
            self.reconnect()
        log.debug("received response: %r", self.device_id)
d = Device()
d.connect()
while True:
    d.receive()

Однако тот же код, заключенный в многопоточность. Класс Thread вызывает взаимные блокировки и забавное поведение.Обмотка замками ничего не изменила.Я проследил проблему до вызова socket.recv () ... Итак, как реализовать несколько потоков, где каждый поток владеет одним сокетом (1 поток владеет исключительно одним сокетом), которые могут одновременно ожидать данные?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 24 апреля 2011

Я знаю, что это не отвечает на ваш вопрос о том, как решить проблему взаимоблокировки, однако в вашем случае это выглядит так, как будто вы используете потоки:

Вы можете просто использовать один поток, в котором вы используете select(), чтобы выяснить, какой сокет имеет доступные данные, а затем обработать сообщенные данные.Если только обработка не займет много времени или ваш протокол не станет более сложным, select должен быть в порядке и избегать проблем с многопоточностью.

Для получения более подробной информации обратитесь к http://docs.python.org/howto/sockets.html#non-blocking-sockets.

0 голосов
/ 23 апреля 2011

Сколько разных сокетов вы должны прочитать?

  • Если ответ «только один», используйте только одну ветку. Как вы выяснили, добавление другого не поможет вам и только усложнит вашу жизнь.
  • Если ответ «несколько», то один из способов организовать это действительно иметь поток на сокет. recv - это операция блокировки, которая делает поток привлекательным вариантом для организации кода. Каждый поток имеет отдельный сокет и читает из него на досуге. У вас не должно быть проблем и тупиков с этим.

    Блокировки не нужны, если ресурсы не используются совместно. Даже если вы совместно используете ресурсы (ведение журнала, некоторое хранилище данных и т. Д.), Не просто используйте простые блокировки - для этого в Python есть утилиты более высокого уровня, такие как модуль Queue.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...