Можно ли использовать мьютекс для блокировки элемента в векторе, а не всего вектора? - PullRequest
4 голосов
/ 30 октября 2011

Можно ли использовать мьютекс для блокировки элемента в векторе, а не всего вектора?

Например, задан вектор myVec;отодвиньте 10 элементов в myVec

  for (int i = 0; i < 10; ++i)
  {
          buffer myBuf = i; // actually myBuf is not necessarily int.
          myVec.push_back(myBuf);
  }

Каждый элемент вектора будет асинхронно изменяться несколькими потоками.Как использовать мьютекс для блокировки только одного буфера в myVec, чтобы один поток мог писать или читать элемент;другой может читать и писать другой элемент одновременно?

спасибо

Ответы [ 2 ]

4 голосов
/ 30 октября 2011

То, что вы хотите, и проще, и сложнее, чем вы думаете:

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

2 голосов
/ 30 октября 2011

Если вектор инициализируется при запуске, он похож на массив фиксированного размера, поэтому нет необходимости его блокировать. Я бы предпочел массив в этой точке :), выделенный с новым [], если хотите.

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

Если один поток обращается только к одному ресурсу для чтения и записи, и этот ресурс не доступен ни одному другому потоку, проблем абсолютно не возникает! Вам не нужен замок.

Если доступ к одному ресурсу между несколькими потоками возможен только в режиме только для чтения, блокировка не требуется.

И если было неясно, в вашем случае array[i] - это ресурс для чтения / записи, а array - это общий ресурс только для чтения.

Если вам нужно синхронизировать каждый элемент, вам нужен мьютекс для каждого элемента. Если есть m ресурсов, к которым обращается m потоков, вам нужно заблокировать ресурсы, используя n мьютексов. Они не дорогие.

Если у вас действительно слишком много ресурсов, вы можете заблокировать части массива: один мьютекс сделает ваше приложение однопоточным, но вы можете, например, назначить 1 мьютекс на каждые 10 элементов. Таким образом вы уменьшаете количество мьютексов, но в то же время гарантируете, что не слишком много потоков не останавливаются вместе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...