Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: mezmay от Февраль 22, 2015, 18:02



Название: Продумать синхронизацию потоков
Отправлено: mezmay от Февраль 22, 2015, 18:02
2 потока: GUI и обработки звука. В GUI потоке надо изменять объект фильтра, который потом используется в звуковом потоке для обработки в реальном времени. Любые блокирующие операции применять нельзя в звуковом потоке, так как сразу идут разрывы. Поэтому мьютексы и спинлоки отпадают.
Думаю надо сделать два оъекта-фильтра и два указателя на них (pointer_gui, pointer_sound), которые надо менять местами каждый раз после изменения фильтра в GUI потоке.
Код:
pointer_gui = pFilter_1;
pointer_sound = pFilter_2;
...

pointer_gui->init(/* параметры фильтра */);
swap(pointer_gui, pointer_sound);
Я правильно понимаю? И это по-хорошему надо сделать через QAtomicPointer, как?



Название: Re: Продумать синхронизацию потоков
Отправлено: mezmay от Февраль 22, 2015, 19:23
Нет, эта фигня не работает. Вообще смысла нет менять указатели, поток-то работает с объектом. То есть обрабатывается звук, а в этот момент GUI поток перебросил указатели и пишет в тот же объект...
На данный момент сделано так: в звуковой поток передаю параметры фильтра и уже в нём (звуковом потоке) инициализирую объект фильтра. Плюс в том, что надо просто передать значения переменных типа float. Минус - в том что инициализировать приходится в звуковом потоке, где лишние операции не нужны.

То есть полноценной синхронизации сейчас нет - примитивы синхронизации использовать нельзя, события тоже использовать нельзя, т.к. нет доступа к управлению звуковым потоком (звук написан с использованием библиотеки Jack audio connection kit). Пока в голове только один вариант - циклический буфер объектов-фильтров.


Название: Re: Продумать синхронизацию потоков
Отправлено: Igors от Февраль 23, 2015, 12:22
Нет, эта фигня не работает. Вообще смысла нет менять указатели, поток-то работает с объектом. То есть обрабатывается звук, а в этот момент GUI поток перебросил указатели и пишет в тот же объект...
А если писать в новый объект и затем перебросить указатели?


Название: Re: Продумать синхронизацию потоков
Отправлено: mezmay от Февраль 23, 2015, 15:55
Нет, эта фигня не работает. Вообще смысла нет менять указатели, поток-то работает с объектом. То есть обрабатывается звук, а в этот момент GUI поток перебросил указатели и пишет в тот же объект...
А если писать в новый объект и затем перебросить указатели?
Пробовал делать так, но начинает тормозить (проц довольно слабый) из-за постоянной операции new


Название: Re: Продумать синхронизацию потоков
Отправлено: Bepec от Февраль 23, 2015, 16:00
А зачем New постоянно? сделайте 2 объекта. В один пишете, второй читается. Потому тупо меняете местами :)


Название: Re: Продумать синхронизацию потоков
Отправлено: Igors от Февраль 23, 2015, 17:04
Пробовал делать так, но начинает тормозить (проц довольно слабый) из-за постоянной операции new
Откуда такая частота? Вообще плохо Вас понял. Есть широко известный прием который иногда называют "фотографией". Есть указатель используемый рабочей ниткой. Другая нитка (часто главная) готовит новые данные и (когда все готово) замещает используемый указатель. Операция замены атомарна. Почему это стандартное решение Вас не устраивает - неясно


Название: Re: Продумать синхронизацию потоков
Отправлено: mezmay от Февраль 23, 2015, 20:39
Замена указателей меня не устраивает т.к. ничего не дает. Потому что нужно объекты менять а не просто указатели. Чтобы GUI поток не писал в рабочий объект


Название: Re: Продумать синхронизацию потоков
Отправлено: Bepec от Февраль 23, 2015, 21:08
Походу у него проблемы с C++. :)


Название: Re: Продумать синхронизацию потоков
Отправлено: mezmay от Февраль 23, 2015, 22:03
Ну так помогите разобраться, если видите что я чего-то не понимаю.
В данный момент непонятно: звуковой поток получил нужный указатель и работает с объектом, на который он указывает. В это время gui поток поменял указатели и пишет в тот же объект


Название: Re: Продумать синхронизацию потоков
Отправлено: Igors от Февраль 24, 2015, 07:48
Ну так помогите разобраться, если видите что я чего-то не понимаю.
В данный момент непонятно: звуковой поток получил нужный указатель и работает с объектом, на который он указывает. В это время gui поток поменял указатели и пишет в тот же объект
Зачем "в тот же" если нужно в другой, а потом подменить. Псевдокод
// gui поток
Код
C++ (Qt)
std::shared_ptr <SoundData> theMainData(new SoundData);  // глобальная переменная
theMainData->Init(...);  // заполняем данные
soundThread.start();  // запускаем звуковой
 
// установка новых данных "на ходу"
void SetNewData( ... )
{
 std::shared_ptr <SoundData> temp(new SoundData); // создаем новые данные
 temp->Init(...);  // заполняем их
 ...
 theMainData = temp;  // устанавливаем новый указатель
}
// Звуковой поток
Код
C++ (Qt)
std::weak_ptr <SoundData> theCurrentData = theMainData; // текущие данные
// работаем с текущими данными theCurrentData
...
// перегружаем данные
theCurrentData = theMainData;
После SetNewData в памяти будут 2 копии данных: новая и старая (с которой еще работает звуковой). Когда звуковой решит что можно заместить данные на новые, он выполнит присваивание (последняя строка), это вызовет удаление старых

Походу у него проблемы с C++. :)
А здесь все не так уж просто. Переставить указатели - ума много не надо, но что делать со старым? Ведь удалить его просто так нельзя, он в использовании  


Название: Re: Продумать синхронизацию потоков
Отправлено: mezmay от Февраль 24, 2015, 08:36
В это время gui поток поменял указатели и пишет в тот же объект
В каком случае может быть эта ситуация если я переставляю после записи? Только если за время чтения в звуковом потоке gui поток успеет более одного раза записать?


Название: Re: Продумать синхронизацию потоков
Отправлено: Igors от Февраль 24, 2015, 09:49
В это время gui поток поменял указатели и пишет в тот же объект
В каком случае может быть эта ситуация если я переставляю после записи? Только если за время чтения в звуковом потоке gui поток успеет более одного раза записать?
Да, эта ситуация называется "ABA". Но и без нее, если у Вас структура данных, то просто "перестановка" не будет работать корректно, напр
Код
C++ (Qt)
// звуковой
SoundData * data;
...
if (data->param1 && data->param2) ...
Так может выйти что param1 был считан из "старых" данных, а param2 - уже из "новых". А если главная нитка уже грохнула старые, то вообще вылет. Поэтому юзайте шаред


Название: Re: Продумать синхронизацию потоков
Отправлено: mezmay от Февраль 24, 2015, 10:57
Спасибо, пока все понятно