Russian Qt Forum
Ноябрь 27, 2024, 08:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Объясните идею Mutex :)  (Прочитано 10830 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« : Январь 27, 2009, 16:07 »

Доброго времени суток!

имеется класс:
Код:
class MyClass
{
public:
   int getValue();
   void setValue(int value);
private:
   int val;
.......
}

Код:
int MyClass::getValue
{
   //QMutexLocker locker(&mutexValue) - нужно ли????
   return val;
}

void MyClass::setValue(int value)
{
   //QMutexLocker locker(&mutexValue) - нужно ли????
   val = value;
}

нужно ли в данном случае защищать переменную val мьютексами Непонимающий
при условии что где-то в приложении очень активно и часто вызываются ф-ции getValue и setValue (например их разные потоки вызывают и т.п) и необходимо писать/читать переменную по возможности как можно быстрее

я это спросил к тому - например мне в принципе не важно успеет прочитаться предыдущ значение переменной val до ее изменения или нет!!!
т.е пусть другие потоки меняют когда и как хотят эту переменную - мне не важно!

т.е какой-то поток постоянно обновляет данные , вызывая setValue , а другой поток постоянно читает getValue

или я шо-то не пойму! Улыбающийся

 
« Последнее редактирование: Январь 27, 2009, 16:12 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Laex
Гость
« Ответ #1 : Январь 27, 2009, 16:51 »

Конкретно в твоём случае мутекс не нужен, т.к. данные типа int и их нельзя прочитать на половину. Вот если бы у тебя был QString вместо int то мутекс бы тебе был необходим т.к. поток может быть прерван "посередине" записи. Например:
Поток 1:
str = "Begin 1 string bla-bla end 1 string"
Поток 2 пытается писать:
str = "Begin 2 string bla-bla end 2 string"
но прерван "посередине" записи потоком 1, который читает из str.
В результате поток 1 получит
"Begin 2 string bla-bla end 1 string"

Только в том случае, когда поток может быть прерван "посередине" операции, которая должна быть атомарной, другим потоком использующем те же данные надо использовать мутексы.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #2 : Январь 27, 2009, 17:37 »

Mutex нужен, т.к. присваивание это не атомарная операция
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Laex
Гость
« Ответ #3 : Январь 27, 2009, 17:55 »

Присваивание int атомарная операция т.к. в конце всё сводится к чтото типа:
Код:
mov [data_ptr],eax
Всё что было до этого(вычисление адреса и т.д.) не влияет на данные.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #4 : Январь 27, 2009, 18:57 »

Всё что было до этого(вычисление адреса и т.д.) не влияет на данные.

Это интересно. Я у меня другая информация, что это есть частный случай и платформозависим. Именно поэтому в Qt имеется класс QAtomicInt.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Dendy
Гость
« Ответ #5 : Январь 27, 2009, 19:39 »

Конкретно в твоём случае мутекс не нужен, т.к. данные типа int и их нельзя прочитать на половину. Вот если бы у тебя был QString вместо int то мутекс бы тебе был необходим т.к. поток может быть прерван "посередине" записи.

Всё с точностью до наоборот. Присваивание int может быть неатомарно на разных платформах. Как сказал Павел - для этого в Qt ввели класс QAtomicInt.
Изменение же QString - операция атомарная, так как он построен по принципу Copy On Write, причём разделение данных сделано атомарными операциями.

Вам и топикстартеру:
http://doc.trolltech.com/4.4/atomic-operations.html
http://doc.trolltech.com/4.4/shared.html
http://doc.trolltech.com/4.4/explicitly-shared.html
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #6 : Январь 27, 2009, 21:04 »

от туда же:
QString, All the functions in this class are reentrant, ....
Записан

Юра.
Dendy
Гость
« Ответ #7 : Январь 27, 2009, 21:14 »

от туда же:
QString, All the functions in this class are reentrant, ....

Голый int тоже reentrant. Автор спрашивал про thread-safe.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Январь 28, 2009, 08:32 »

1. а если переменная VAL имеет тип QVariant или является какой нить структурой?

2. если я введу мьютекс, то на сколько примерно упадет скорость работы с этой переменной? как это можно оценить?

3. сколько вносят задержки сам вызов и выполнение функций getValue и setValue (примерно), ведь можно чтобы уменьшить время обработки - просто объявить эту переменную как Public (теоретически) Улыбающийся


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

« Последнее редактирование: Январь 28, 2009, 08:41 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
Dendy
Гость
« Ответ #9 : Январь 28, 2009, 11:02 »

1. Нужно смотреть какой тип переменой в каждом случае. Даже с простыми типами код нужно делать потокобезопастным. Кстати, интересный вопрос по QVariant, ни в документации, ни судя по коду он НЕ потокобезопастный, поправьте если я неправ.

2. Пишите простой цикл и меряете сколько выполняется миллион итераций с мутексами и без.

3. Если методы inline - тогда никакой разницы. Вообще нужно смотреть по ситуации, смотря какая задача.

Если у вас более одной переменной в структуре типа - тоже нужно добавлять потокобезопастность. Варианты:
1. С помощью мутексов.
2. Обьединить данные в структуру и засунуть её в QSharedDataPointer. Данные будут выделяться в памяти и происходить лишнее разименование, зато будут отсутствовать мутексы, а следовательно и накладные расходы с ними связанные.
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #10 : Январь 28, 2009, 13:52 »

Спасибо большое! Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Swappp
Гость
« Ответ #11 : Январь 28, 2009, 20:42 »

А у меня такой вопрос по поводу потокобезопасности int:
Есть приложение, главный поток занимается отрисовкой GUI как и положено. Создается второй поток, который производит некоторые вычисления. В главном потоке несколько раз в секунду производится чтение и отрисовка значения из int, которое в этот же момент может изменятся во втором потоке. Корректность отрисовываемых данных не критична. Т.е. ничего страшного, если там будет нарисовано какое-то не то значение, т.к. все равно если значение часто меняется (частота перерисовки превышает 25 кадров в сек.), его и так не возможно точно прочитать, главное видеть меняется ли оно и возможно примерно определять старшие разряды. Так вот, могут ли на разнообразных платформах в принципе возникнуть какие-нибудь другие проблемы, кроме отрисовки некорректных данных?
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #12 : Май 13, 2010, 17:09 »

А нужен ли QMutex для метода, в котором происходит только чтение (напр. контейнера) без изменения его содержимого? К этому методу обращается множество потоков. По-идее не нужен ведь?
« Последнее редактирование: Май 13, 2010, 17:15 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
ритт
Гость
« Ответ #13 : Май 13, 2010, 18:40 »

если этот контейнер после старта данных потоков(а) никем и никогда не изменяется, защищать не нужно.
Записан
spectre71
Гость
« Ответ #14 : Май 13, 2010, 19:33 »

если этот контейнер после старта данных потоков(а) никем и никогда не изменяется, защищать не нужно.

И если при чтении данных из контейнера не изменяются никакие его внутренние переменные/поля/глобалы (что вполне возможно, и зависит от реализации конкретного контейнера)
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.055 секунд. Запросов: 23.