Прежде всего, к некоторым постам и комментариям, с каких пор документация была надежной?
Во-вторых, этот ответ больше относится к общему вопросу, чем к особенностям ОП.
Я согласен с MrFox в теории, потому что все сводится к двум вопросам:
- Реализован ли класс List в виде плоского массива?
Если да, то:
- Может ли инструкция записи быть выгружена в середине записи>
Я полагаю, что это не так - полная запись произойдет до того, как кто-либо сможет прочитать этот DWORD или что-то еще. Другими словами, никогда не случится, что я запишу два из четырех байтов DWORD, а затем вы прочитаете 1/2 нового значения и 1/2 старого.
Итак, если вы индексируете массив, предоставляя смещение некоторому указателю, вы можете безопасно читать без блокировки потоков. Если список выполняет больше, чем просто математика указателей, он не является поточно-ориентированным.
Если бы в Списке не использовался плоский массив, я думаю, вы бы сейчас увидели его крах.
Мой собственный опыт показывает, что чтение одного элемента из списка безопасно с помощью индекса без блокировки потоков. Хотя это все ИМХО, так что принимайте это за то, что оно стоит.
В худшем случае, например, если вам нужно перебрать список, лучше всего сделать следующее:
- заблокировать список
- создать массив одинакового размера
- используйте CopyTo () для копирования списка в массив
- разблокировать список
- итерируйте массив вместо списка.
in (как вы называете .net) C ++:
List<Object^>^ objects = gcnew List<Object^>^();
// in some reader thread:
Monitor::Enter(objects);
array<Object^>^ objs = gcnew array<Object^>(objects->Count);
objects->CopyTo(objs);
Monitor::Exit(objects);
// use objs array
Даже с выделением памяти это будет быстрее, чем блокировка списка и повторение всего объекта перед его разблокировкой.
Только наперед: если вам нужна быстрая система, блокировка потоков - ваш злейший враг. Используйте взамен ZeroMQ . Я могу говорить по опыту, синхронизация на основе сообщений - верный путь.