Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> использование bool в многопоточном приложении 
V
    Опции темы
georain
Дата 10.6.2008, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



В многопоточном приложении есть переменная состояния bool с блокировками при её установке и чтении, например так:
Код

    bool a;

Код

lock()
    bool = true;
unlock()

Код

lock()
    bool b = a;
unlock()
    if(b){...};

Будет ли что-то страшное если убрать блокировку?
Честно говоря я не вижу смысла её тут ставить.

P.S. Поделитесь опытом работы с bool типами в многопоточности. Тут вроде не происходит чтения перед записью, только запись, а запись происходит как бы одной операцией, что может поломаться то (если рядом с установкой/чтением больше ничего нет), зачем блокировать?

Это сообщение отредактировал(а) georain - 11.6.2008, 00:12
PM MAIL   Вверх
andrew_121
Дата 10.6.2008, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



bool не чем не отличаеться от обычных переменных типа int, кроме того что принимает только два значения - true, false.
Если к переменной, доступ получают несколько потоков, тогда блокировка необходима.

Это сообщение отредактировал(а) andrew_121 - 11.6.2008, 00:53


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
georain
Дата 11.6.2008, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Цитата(andrew_121 @  10.6.2008,  23:56 Найти цитируемый пост)
Если к переменной, доступ получают несколько потоков, тогда блокировка необходима. 

Это я уже слышал, меня интересует почему? Что случится если блокировки не будет? (только применительно к bool)

Моё понимание что происходит с int:
В одно и тоже время один поток хочет увеличить int на 5, другой тоже хочет увеличить int на 10.
С блокировкой: они последовательно увеличивают int (пока один делает операции, второй ожидает), в итоге int увеличивается на 15.
Без блокировки: первый поток читает int из памяти и заносит в регистр ЦП, второй делает тоже самое, первый поток увеличивает это значение на 5 (в регистре ЦП), второй делает тоже самое на 10, первый поток записывает int в память, второй делает тоже самое, в итоге в памяти оказывается значение одного из двух регистров. Мало того что int увеличился не на 15 а на 10 или 5, непонятно на 5 или на 10 он увеличился smile
А с bool то что будет?

Это сообщение отредактировал(а) georain - 11.6.2008, 00:15
PM MAIL   Вверх
andrew_121
Дата 11.6.2008, 00:56 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



boob - принимает только два значения - true, false.
Допустим, один поток хочет получить значение переменной, а другой, в это же время, изменить. Что произойдет без блокировки? Секёшь?

Примерчик:
Код

void LTimer::set_millisecond( luint32 p ) {
    LMutex mutex; // Мьютекс
    LMutexLock locker( &mutex ); // Локер
    _interval = p;
}
//---------------------------------------------------------------------------
void LTimer::set_second( luint32 p ) {
    LMutex mutex; // Мьютекс
    LMutexLock locker( &mutex ); // Локер
    _interval = p * 1000;
}


Это сообщение отредактировал(а) andrew_121 - 11.6.2008, 01:16


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
georain
Дата 11.6.2008, 01:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Нет не секу, расскажи.
PM MAIL   Вверх
andrew_121
Дата 11.6.2008, 01:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



Код


class Primary {
public:
   Primary():stat(false) {}
   bool GetStat() const { return stat; }
   void SetStat(bool st) { stat = st; }
private:
   bool stat;
};

int main() {

   Primary primary;

   Thread thread1, thread2;
   // Кароче. "thread1" и "thread2", в произвольном порядке, вызывают методы GetStat() и SetStat() объекта Primary.
   // У одного из них, результат работы зависит, от полученного значения. Какой из них будет получать правильное значение?

   return 0;
}



Это сообщение отредактировал(а) andrew_121 - 11.6.2008, 01:32


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
georain
Дата 11.6.2008, 01:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Цитата(andrew_121 @  11.6.2008,  01:30 Найти цитируемый пост)
Какой из них будет получать правильное значение?

А какой из них будет получать правильное значение при наличии блокировки?
Другими словами, что изменится при введении блокировок в твой пример?

Это сообщение отредактировал(а) georain - 11.6.2008, 01:38
PM MAIL   Вверх
andrew_121
Дата 11.6.2008, 01:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 6
Всего: 33



А вот тут тебе нужно позаботиться о синхронизации.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
georain
Дата 11.6.2008, 01:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Добавление блокировок в твой пример ничего не даст, а "позаботится о синхронизации" имхо означает создание полезного кода из бесполезного примера.
andrew_121, давай прервём нашу беседу до прихода специалистов.

Добавлено через 13 минут и 23 секунды
ИМХО, при использовании bool блокировать нужно только в конструкции
Код

lock()
    if( a == true ) a = false;
    else            a = true;
unlock()

и производных от неё. Все остальные случаи представляют собой только а) чтение и б) запись без предварительного чтения, а значит не нуждаются в синхронизации.
Я могу быть не прав! Поправьте меня аргументами или примерами

Это сообщение отредактировал(а) georain - 11.6.2008, 01:46
PM MAIL   Вверх
Palladin
Дата 11.6.2008, 05:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 932
Регистрация: 15.5.2007
Где: Беларусь г.Гомель

Репутация: нет
Всего: 17



Цитата(georain @  10.6.2008,  23:49 Найти цитируемый пост)
Честно говоря я не вижу смысла её тут ставить.

Не видете смысла, не ставьте, если смысл появится вы, по всей видимости, это поймете и сделаете, то что нужно! 
Не ждите "специалистов", какие гарантии что их ответ верен? 
Не полагайтесь на истину авторитета, полагайтесь на авторитет истины smile 
P.S. Слушать кого-то нужно лишь в случае когда надо срочно что-то делать, а вы незнаете как, сейчас по всей видимости вы изучаете, а значит изучайте smile

Добавлено через 2 минуты и 36 секунд
И не зачем грубить форумчанам, если вы не заметили andrew_121, изо всех сил старался помочь... 


--------------------
Глуп тот кто полагается на истину авторитета, а не на авторитет истины
[color=red]KAV&KIS==Evil[/color]
PM MAIL   Вверх
Lazin
Дата 11.6.2008, 05:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



bool - атомарный тип, причем значение ему обычно присваивается, не прибавляется, не вычитается и тд... так что можно без блокировок обойтись..
блокировать нужно немного по другому
Код

bool need_to_work = true;
...
lock();
if (need_to_work)
{
    need_to_work = false;
    //код который должен выполнится 1 раз
}
unlock();

если здесь не блокировать то код может выполнится 2 раза и более
в принципе могут портиться даже переменные атомарных типов, если они изменяются одновременно из разных потокв, но поскольку для bool актуально только присваивание и сравнение, то тут
Цитата

Код

class Primary {
public:
   Primary():stat(false) {}
   bool GetStat() const { return stat; }
   void SetStat(bool st) { stat = st; }
private:
   bool stat;
};


можно вообще не блокировать..
PM MAIL Skype GTalk   Вверх
georain
Дата 11.6.2008, 08:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Цитата(Palladin @  11.6.2008,  05:26 Найти цитируемый пост)
И не зачем грубить форумчанам, если вы не заметили andrew_121, изо всех сил старался помочь...  

Я ни в коем случае не хотел нагрубить, andrew_121, если я вас обидел, сильно прошу прощения. Я благодарен за вашу помощь, она навела на правильные мысли smile

Lazin, спасибо!

Т.е. в случае:
Код

bool need_to_do_it = true; // изменяется в одном потоке
...

if( need_to_do_it ) // выполняется в другом потоке
{
    //код в котором нет обращений к need_to_do_it
}

блокировать где-либо не надо?

А таком случае:
Код

int var = 123; // изменяется в одном потоке
...

if( var == 500 ) // выполняется в другом потоке
{
    //код в котором нет обращений к var
}

в "другом" потоке (с if) блокировать тоже не надо?
PM MAIL   Вверх
Palladin
Дата 11.6.2008, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 932
Регистрация: 15.5.2007
Где: Беларусь г.Гомель

Репутация: нет
Всего: 17



Вы видимо про else данного иф, ненадо


--------------------
Глуп тот кто полагается на истину авторитета, а не на авторитет истины
[color=red]KAV&KIS==Evil[/color]
PM MAIL   Вверх
Lazin
Дата 11.6.2008, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



если операция сравнения и присваивания для инт атомарна, тоесть переключение контекста не может произойти во время операции с этим типом, то не надо..
но если операция не атомарна, то она может выполняться так:

в случае одного потока:
__________________________________________
var == 10
копирование в регистр из памяти значения переменной    reg = var; reg == 10
изменение значения                                                               reg += 10 
копировани из регистра в память                                          var = reg
var == 20

2 потока:
1й поток                                           2й поток
__________________________________________________________________________________
var == 10
копирование в регистр из памяти значения переменной                                                                          reg1 = var

                                                           копирование в регистр из памяти значения переменной               reg2 = var; reg2 == 10
                                                           изменение значения                                                                          reg2 += var
                                                           копирование из регистра в память                                                   var = reg2; var == 20

изменение значения в регистре 
(оно не учитывает изменения внесенные 2-м потоком)
                                                                              reg1 += 10; reg1 == 20
копирование из регистра в память                                                                                                              var = reg1; var == 20!!
var == 20

Добавлено @ 09:44
конечно шансов что так произойдет мало.. и в большинстве случаев в переменную запишется значение 30, но все-же
проще все-же разрабатывать систему блокировок на уровне классов.. для разных объектов должны быть свои блокировки, вот так, на уровне кода очень сложно это делать..
я обычно использую блокировки вот так:

Код

void method()//метод изменяет объект, 
//когда он выполняется другие методы этого объекта должны ждать
//ждет когда отработают все методы method2 в других потоках
{
  lock_read_and_write();
  ///code
  unlock();
}

void method2() const //метод не изменяет объект, 
//можно одновременно вызывать из разных потоков
//но только если не вызван метод method в одном из потоков
{
  lock_write();
  //code
  unlock();
}


lock_write - блокировка изменения объекта - shared read
lock_read_and_write - блокировка записи и чтения - exclusive write

Это сообщение отредактировал(а) Lazin - 11.6.2008, 09:45
PM MAIL Skype GTalk   Вверх
georain
Дата 11.6.2008, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 193
Регистрация: 28.11.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Картина становится ясна. А операции "чтение" и "запись (без предварительного чтения в регистр)" всегда атомарны? Переключение контекста может произойти во время этих операций? Т.е. например в памяти находится 01, первый поток хочет записать 10, а  второй поток в это время читает, может он в итоге прочитать 11 или 00, или всегда либо 01 либо 10?

Это сообщение отредактировал(а) georain - 11.6.2008, 09:55
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0940 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.