Асинхронный потокобезопасный семафор Python

Я ищу поточно-ориентированную реализацию семафора, которую можно использовать в Python.

Стандартные библиотеки asyncio.Semaphore не являются потокобезопасными.

Стандартные библиотеки threading.Semaphore не имеют awaitable интерфейса.

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

ОБНОВЛЕНИЕ: я имел в виду здесь процесс, а не потоки. Итак, должно быть так, что Sanic разделяется на процессы и multiprocessing.Semaphore. Я считаю, что данный ответ по-прежнему актуален для того, где я могу применить аналогичное решение.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы говорите, что вам нужен один экземпляр семафора, который будет использоваться во всех потоках, создайте экземпляр threading.Semaphore и асинхронную функцию acquire_semaphore, например:

import asyncio
import threading
from concurrent.futures import ThreadPoolExecutor

executor = ThreadPoolExecutor()
semaphore = threading.Semaphore()

async def acquire_semaphore():
    """Make a threading.Semaphore awaitable."""

    def acquirer():
        semaphore.acquire()

    loop = asyncio.get_running_loop()
    await loop.run_in_executor(executor, acquirer)

async def test():
    """Acquire and release a semaphore sharable across threads."""

    await acquire_semaphore()
    print('acquired')
    await asyncio.sleep(1)
    semaphore.release()  # This never blocks
    print('released')


def worker():
    asyncio.run(test())

def main():
    threads = [
        threading.Thread(target=worker)
        for _ in range(3)
    ]

    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()

if __name__ == '__main__':
    main()

Распечатки:

acquired
released
acquired
released
acquired
released

Другие вопросы по теме

Похожие вопросы

Должен ли таймер захватывать все время создания списка?
Почему результаты AES-256-CBC в PHP и Python различаются при использовании одних и тех же ключей и данных?
С использованием attrs pre-commit ошибка mypy: неожиданный аргумент ключевого слова
Получение группового ключа при использовании группы путем применения (списка)
Почему pytorch tensor.item() дает неточный вывод для любого ввода действительного числа, но дает точный вывод для числа, которое заканчивается на .0 или .5?
Рассчитать количество точек заданного радиуса по координатам X и Y
Почему некоторые функции регулярных выражений возвращают объект соответствия, а некоторые нет?
Группируйте элементы в фрейме данных и отображайте их в хронологическом порядке
Операции Pandas между типами с плавающей запятой и NaN
Используйте спецификатор формата для преобразования столбца float/int в фрейме данных Polars в строку