2012-01-26 2 views
6

Интересно, являются ли функции размера (размер, длина или что-то еще) потокобезопасными? Как я понимаю, они обычно просто возвращают часть частного размера. Я действительно сомневаюсь, что они делают какие-то расчеты. Все они отмечены как const, но они потокобезопасны? например std :: list :: размер?функции размера и безопасность потока в C++

У меня есть функция защиты от блокировки для записи и другая для чтения (также защищена от блокировки), но мне интересно, должна ли моя функция быть заблокирована? ИМО, это выглядит пустой тратой времени отклика. Я не думаю, что он может сломать любые итераторы или потерпеть неудачу, если какой-то член удаляется из списка одновременно (насколько это возможно).

+1

'счет' * есть * считывание. Если вы заблокируете другие операции чтения, почему бы вам не заблокировать «count»? Что делает его особенным? –

ответ

6

Да, его необходимо защитить замком. Предположим, что ваша реализация std::list::size - это 32-битное значение, но на вашей платформе 32-битные чтения не являются атомарными, они берут 2 16-битных чтения. В этом случае второй поток может прерывать первый, который считывал размер после первого чтения, обновлять переменную размера, а затем, когда происходит второе 16-разрядное чтение, вы можете получить реальное испорченное значение для размера.

+1

Это объясняет, почему он не очень безопасен для потоковой передачи. Спасибо. – Pijusn

4

Нет, они не являются потокобезопасными. Стандартные контейнеры просто не потокобезопасны, периоды.

Существует, однако, ограниченное количество потоков безопасности: если каждый поток обращается к различным элементам, и ни один элемент не доступен двумя различными потоками в любой момент времени, тогда это нормально. Однако любая операция, которая мутирует сам контейнер (вставка, стирание), не является потокобезопасной, а должен быть синхронизирован. Следовательно, итераторы и ссылки могут потерять свою актуальность, и аналогично затронуто и size().

Другими словами, если вы разделите все операции, которые мутируют контейнер из тех, которые не делают, то пока вы не мутирует, вы можете безопасно вызывать size() из нескольких потоков.

+2

Утверждение, что стандартные контейнеры «просто не потокобезопасны, период» ** очень ** вводит в заблуждение! Они обеспечивают очень разумную форму безопасности потока. Просто потому, что некоторые люди хотят какой-то потоковой безопасности, где они могут жить, не заботясь о брейках, получая все преимущества, не означает, что они не являются потокобезопасными! Тот факт, что люди не понимают, что доступ даже к примитивному значению требует синхронизации, является частью проблемы, с которой они связаны с потоками. –

Смежные вопросы