Multithreading: как очередь, но вручную и красиво?
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 15.01.26 09:56
Оценка:
Периодически возникает при многонитевом построении примерно следующий "паттерн": есть элемент состояния/управления (как очередь заданий), который требует контролируемого взаимодействия с помощью лока и "условной переменной". Но чтобы на время выполнения задания не блокировать тех, кто хочет установить следующее задание, лок снимается на это время. Получается следующая схема:

## Псевдокод в стиле Python
with self.lock: ## для C++ аналог -- захват лока в конструкторе
    while True:
        if not self.task: ## можно было и с предикатом, если кому удобнее читать
            self.cv.sleep()
            continue
        task = self.task
        self.task = None
        self.lock.release() ## начинается длительная операция
        try:
            self.execute(task)
        except Exception:
            ... пожаловались ...
        self.lock.acquire()


Мне не нравится в нём именно "ручное" освобождение и последующее занятие лока вокруг длительной работы. RAII или with-оператор придумали не просто так, если есть возможность взвалить контроль на них, то лучше этим воспользоваться.

Можно было бы просто перевести на очередь. Но бывает, что при этом ещё и какие-то элементы статуса отдаются обратно, или воздействие от управляющего метода более сложное. И если может быть поставлено не более одного задания, то делать это в виде очереди, ограниченной одним элементом, тоже как-то странно. Ещё бывают собственные idle операции, а ждать чтения из очереди с таймаутом не всегда возможно.

Какие есть варианты сделать это красиво без подобных ручных плясок?
The God is real, unless declared integer.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.