Есть х ++; потокобезопасны?

Если я обновлю переменную в одном потоке, как это:
receiveCounter ++;

а затем из другого потока я только когда-либо читал эту переменную и записывал ее значение в графический интерфейс.

Это безопасно? Или эта инструкция может быть прервана посередине, поэтому значение в receiveCounter неверно, когда оно читается другим потоком? это должно быть так правильно, поскольку ++ не атомарен, это несколько инструкций.

Меня не волнует синхронизация чтения и записи, ее просто нужно увеличить, а затем обновить в графическом интерфейсе, но это не должно происходить непосредственно друг за другом.

Меня волнует, что значение не может быть неправильным. Например, операция ++ прерывается в середине, поэтому значение чтения полностью отключено.

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

Но меня все равно интересует вышеуказанная проблема.

3

Решение

По своей сути это операция чтения-изменения-записи, они не являются атомарными. Есть несколько процессоров, у которых есть специальная инструкция для этого. Как и ядра Intel / AMD, они очень распространены и имеют инструкцию INC.

Пока что звуки как это может быть атомарным, так как это единственная инструкция, это все еще не так. Набор команд x86 / x64 больше не имеет ничего общего с тем, как на самом деле реализован механизм исполнения. При выполнении RISC-подобных «микроопераций» инструкция INC транслируется в несколько микроопераций. Это Можно быть сделанным атомарным с префиксом LOCK в инструкции. Но компиляторы не выдают это, если они знать что атомное обновление желательно.

Таким образом, вам нужно быть откровенным об этом. C ++ 11 std :: atomic<> Стандартное дополнение это хороший способ. Ваша операционная система или компилятор будут иметь встроенные функции, обычно называемые как-то вроде «Interlocked» или «__built_in».

2

Другие решения

Если один поток изменяет значение в переменной, а другой поток считывает это значение, и программа не синхронизирует доступы, это имеет гонку данных, и поведение программы не определено. Изменить тип receiveCounter в std::atomic<int> (при условии, что это int начать с)

2

++ эквивалентно i=i+1,

++ это не atomic operation так что это NOT Поток безопасно. Только чтение и запись примитивных переменных (кроме long и double) являются атомарными и, следовательно, потокобезопасными.

1

Простой ответ: НЕТ.

так как i++; так же, как i = i + 1; и он содержит нагрузку, математическую операцию и сохранение значения. так что это не атомная, по крайней мере, 3 операции.

0

Вообще говоря, это не поточно-ориентированный, потому что оператор ++ состоит из одного читать и один записывать, пара которых не является атомной и может быть прервана между ними.

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

(Изм)

Для читать а также записывать Сами по себе операции, если вы не находитесь в 64-битном режиме, они должны быть атомарными, поэтому, если вы не заботитесь о том, чтобы другие потоки имели значение, неправильное на 1, это может подойти для вашего случая.

0

Нет. Операция инкремента не является атомарной, поэтому не является поточно-ориентированной.

В вашем случае безопасно использовать эту операцию, если вы не заботитесь о ее значении в определенное время (если вы только читаете эту переменную из другого потока и не пытаетесь записать в нее). Это в конечном итоге будет увеличиваться receiveCounterЗначение, у вас просто нет никаких гарантий о порядке операций.

0
По вопросам рекламы [email protected]