Как реализовать потоковый socket.recv () в python?

1

У меня есть несколько устройств, из которых мне нужно получить обновления статуса. Объект сокета - это все, что у меня есть, и 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()

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

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

  • 0
    Почему ты ставишь замок? Вы делитесь каким-либо ресурсом? send / recv согласно POSIX - это атомарные операции. Может быть, вы не использовали потоки хорошо. Можете ли вы поделиться кодом, где вы реализовали потоки?
Теги:
multithreading
sockets
locking

2 ответа

0
Лучший ответ

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

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

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

0

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню