Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > использование bool в многопоточном приложении |
Автор: georain 10.6.2008, 23:49 | ||||||
В многопоточном приложении есть переменная состояния bool с блокировками при её установке и чтении, например так:
Будет ли что-то страшное если убрать блокировку? Честно говоря я не вижу смысла её тут ставить. P.S. Поделитесь опытом работы с bool типами в многопоточности. Тут вроде не происходит чтения перед записью, только запись, а запись происходит как бы одной операцией, что может поломаться то (если рядом с установкой/чтением больше ничего нет), зачем блокировать? |
Автор: andrew_121 10.6.2008, 23:56 |
bool не чем не отличаеться от обычных переменных типа int, кроме того что принимает только два значения - true, false. Если к переменной, доступ получают несколько потоков, тогда блокировка необходима. |
Автор: andrew_121 11.6.2008, 00:56 | ||
boob - принимает только два значения - true, false. Допустим, один поток хочет получить значение переменной, а другой, в это же время, изменить. Что произойдет без блокировки? Секёшь? Примерчик:
|
Автор: georain 11.6.2008, 01:14 |
Нет не секу, расскажи. |
Автор: andrew_121 11.6.2008, 01:30 | ||
|
Автор: georain 11.6.2008, 01:35 |
А какой из них будет получать правильное значение при наличии блокировки? Другими словами, что изменится при введении блокировок в твой пример? |
Автор: andrew_121 11.6.2008, 01:39 |
А вот тут тебе нужно позаботиться о синхронизации. |
Автор: georain 11.6.2008, 01:44 | ||
Добавление блокировок в твой пример ничего не даст, а "позаботится о синхронизации" имхо означает создание полезного кода из бесполезного примера. andrew_121, давай прервём нашу беседу до прихода специалистов. Добавлено через 13 минут и 23 секунды ИМХО, при использовании bool блокировать нужно только в конструкции
и производных от неё. Все остальные случаи представляют собой только а) чтение и б) запись без предварительного чтения, а значит не нуждаются в синхронизации. Я могу быть не прав! Поправьте меня аргументами или примерами |
Автор: Palladin 11.6.2008, 05:26 |
Не видете смысла, не ставьте, если смысл появится вы, по всей видимости, это поймете и сделаете, то что нужно! Не ждите "специалистов", какие гарантии что их ответ верен? Не полагайтесь на истину авторитета, полагайтесь на авторитет истины ![]() P.S. Слушать кого-то нужно лишь в случае когда надо срочно что-то делать, а вы незнаете как, сейчас по всей видимости вы изучаете, а значит изучайте ![]() Добавлено через 2 минуты и 36 секунд И не зачем грубить форумчанам, если вы не заметили andrew_121, изо всех сил старался помочь... |
Автор: Lazin 11.6.2008, 05:36 | ||||||
bool - атомарный тип, причем значение ему обычно присваивается, не прибавляется, не вычитается и тд... так что можно без блокировок обойтись.. блокировать нужно немного по другому
если здесь не блокировать то код может выполнится 2 раза и более в принципе могут портиться даже переменные атомарных типов, если они изменяются одновременно из разных потокв, но поскольку для bool актуально только присваивание и сравнение, то тут
можно вообще не блокировать.. |
Автор: georain 11.6.2008, 08:43 | ||||||
Я ни в коем случае не хотел нагрубить, andrew_121, если я вас обидел, сильно прошу прощения. Я благодарен за вашу помощь, она навела на правильные мысли ![]() Lazin, спасибо! Т.е. в случае:
блокировать где-либо не надо? А таком случае:
в "другом" потоке (с if) блокировать тоже не надо? |
Автор: Palladin 11.6.2008, 09:26 |
Вы видимо про else данного иф, ненадо |
Автор: Lazin 11.6.2008, 09:32 | ||
если операция сравнения и присваивания для инт атомарна, тоесть переключение контекста не может произойти во время операции с этим типом, то не надо.. но если операция не атомарна, то она может выполняться так: в случае одного потока: __________________________________________ 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, но все-же проще все-же разрабатывать систему блокировок на уровне классов.. для разных объектов должны быть свои блокировки, вот так, на уровне кода очень сложно это делать.. я обычно использую блокировки вот так:
lock_write - блокировка изменения объекта - shared read lock_read_and_write - блокировка записи и чтения - exclusive write |
Автор: georain 11.6.2008, 09:53 |
Картина становится ясна. А операции "чтение" и "запись (без предварительного чтения в регистр)" всегда атомарны? Переключение контекста может произойти во время этих операций? Т.е. например в памяти находится 01, первый поток хочет записать 10, а второй поток в это время читает, может он в итоге прочитать 11 или 00, или всегда либо 01 либо 10? |
Автор: Lazin 11.6.2008, 10:00 |
на платформе х86 будет либо 10 либо 01, на остальных скорее всего то-же ![]() |
Автор: georain 11.6.2008, 10:06 | ||
Да, конечно. Но блокировка дело не дешёвое и делать её для чтения bool как в примере по моему неразумно. Вот и хочется понять в каких случаях без неё можно обойтись. Например то что тут
можно вообще не блокировать мои коллеги сомневаются и ставят mutex. ![]() Может какая литература есть? |
Автор: vinter 11.6.2008, 10:10 |
я бы ставил блокировку в месте использования данного класса, а уж никак ни в его методах |
Автор: Lazin 11.6.2008, 10:11 |
в этом примере ничего блокировать не надо |
Автор: andrew_121 11.6.2008, 10:15 |
Вот, и меня просветили. Я бы поставил. |
Автор: georain 11.6.2008, 10:16 |
vinter, это ухудшает инкапсуляцию, есть паттерн типа "защищённый класс", все открытые методы начинаются с блокировки. Тогда не надо заботится о защите данных класса. Кроме того это уменьшает область критического кода, да и вообще количество возможных ошибок. Иногда блокировок ой как много бывает. |
Автор: vinter 11.6.2008, 10:27 | ||
зависит от назначения класса, если будет библиотека, то внутренние блокировки не айс, как пример STL |