Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: ti0 от Август 03, 2020, 10:36



Название: Массив буферов producer - customer
Отправлено: ti0 от Август 03, 2020, 10:36
Не могу никак сообразить архитектуру. Есть класс кольцевого буфера. Запись и чтение из которого осущесттвляется с разных потоков. Для синхронизации используется
QWaitCondition и QMutex. Они находятся в классе буфера. Все отлично работает. Но логика приложения усложнилась. Потоки producer и customer могут создаваться в процессе работы программы, при этом взаимосвязь между ними может быть любая. например, может быть конфигурация 1 producer -> buffer -> 2 customer, и одновременно с этим еще 1 producer -> buffer -> 1 customer. Итого у нас 2 кольцевых буфера. Я создал класс BufferManager, где начал использовать QMap<буфер>, но QMap никак не защищен, потому что если использовать QMutex, получается deadlock, когда customer ждет данных, а producer не может их записать, так как QMutex заблокирован customer. Как мне защитить QMap?


Название: Re: Массив буферов producer - customer
Отправлено: qate от Август 03, 2020, 16:37
предлагаю замутить сигнал readyRead, как сделано в QTcpSocket


Название: Re: Массив буферов producer - customer
Отправлено: Igors от Август 04, 2020, 13:31
Для синхронизации используется QWaitCondition и QMutex.
Не "ошибка" но "тревожный симптом". Лучше обойтись чисто сигналами без низкоуровневых примитивов синхронизации.

Но логика приложения усложнилась. Потоки producer и customer могут создаваться в процессе работы программы, при этом взаимосвязь между ними может быть любая. например, может быть конфигурация 1 producer -> buffer -> 2 customer, и одновременно с этим еще 1 producer -> buffer -> 1 customer. Итого у нас 2 кольцевых буфера. Я создал класс BufferManager, где начал использовать QMap<буфер>, но QMap никак не защищен, потому что если использовать QMutex, получается deadlock, когда customer ждет данных, а producer не может их записать, так как QMutex заблокирован customer. Как мне защитить QMap?
Есть "дешевое" решение: заранее создать все буфера и поместить их в QMap. Тогда конкурентный доступ к ней ничем не грозит. Если так не выходит, нужно ставить "свой" QReadWriteLock на эту мапу