LINUX.ORG.RU

Чем грозит использование asyncio.Queue.put_nowait в синхронном коде?

 ,


0

1

Есть такой оверрайд для подсистемы логов:

    def emit(self, record):
        """Overwrite emit method to publish logs to MQTT."""
        msg = self.format(record)
        try:
            self.logs_bridge_queue.put_nowait(msg)
        except asyncio.QueueFull:
            self.logs_bridge_queue.get_nowait()
            self.logs_bridge_queue.put_nowait(msg)

C другой стороны приёмник:

        while True:
            msg = await self.logs_bridge_queue.get()

В документации написано:

Although asyncio queues are not thread-safe, they are designed to be used specifically in async/await code.

Я не могу понять, что они имеют в виду под thread-safe. Все функции вне асинхронного контекста или только threading?

И чем может грозить использование asyncio.Queue вне асинхронного контекста?

★★★★★

Последнее исправление: steemandlinux (всего исправлений: 1)

Я не могу понять, что они имеют в виду под thread-safe. Все функции вне асинхронного контекста или только threading?

Их можно использовать только внутри корутин. Либо в одном потоке. Одновременный доступ из нескольких тредов их сломает. (хотя честно говоря, не понимаю как, потому что в питоне нет параллельного выполнения тредов из-за GIL)

lovesan ★★
()
Ответ на: комментарий от lovesan

Одновременный доступ из нескольких тредов их сломает. (хотя честно говоря, не понимаю как, потому что в питоне нет параллельного выполнения тредов из-за GIL)

Потому что методы в общем случае не атомарны.

http://onreader.mdl.ru/MasteringConcurrencyInPython/content/Ch17.html

qaqa ★★
()
Последнее исправление: qaqa (всего исправлений: 1)
Ответ на: комментарий от qaqa

Это очень смешная херня, на самом деле. Потому что мало того что сделали этот вот GIL, так еще и не осилили сделать все псевдо-атомарным. Хотя по сути он для этого и нужен.

CPython это очень смешное и очень кривое говно.

lovesan ★★
()
Ответ на: комментарий от lovesan

Там так офигенно сделано, что вот этот сишный поллинг вызывает GIL:

https://github.com/libusb/hidapi/blob/baa0dab6114e8654161478e10a20c67cf5d1a1a3/linux/hid.c#L1125

И приходится запускать через run_in_executor.

steemandlinux ★★★★★
() автор топика
    def emit(self, record):
        """Overwrite emit method to publish logs to Node."""
        print(asyncio.get_event_loop())

<_UnixSelectorEventLoop running=True closed=False debug=False>

В общем можно спокойно использовать Queue внутри эмиттера.

steemandlinux ★★★★★
() автор топика