LINUX.ORG.RU

Чтение двумя потоками одних и тех-же данных

 , мьютексы


0

1

Добрый день, я знаю что для предотвращения конфликтов при использовании двумя потоками одной переменной/буфера использую мьютексы.
А можно-ли читать одни и те-же данные из одного и того-же буфера в двух разных потоках одновременно?

Ответ на: комментарий от Boy_from_Jungle

Главное - если что-то кем-то может записываться в буфер, не забывать захватывать мьютекс и при чтении.

ratatosk
()

можно-ли читать одни и те-же данные из одного и того-же буфера в двух разных потоках одновременно?

Даже в трех разных потоках можно. Проблемы возникают, только если Вы каким то потоком пишите, и при этом каким то потоком (или протоками) читаете - тогда неизвестно что там прочитается.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Проблема даже не в том, что неизвестно что прочитается, а в том, увидит ли читающий процесс записанные данные. Блокировки не только для обеспечения корректности данных при чтении записи используются, но и как memory barrier.

Если данные read-only, т.е. после инициализации не меняются, то можно и без блокировок читать, иначе есть шанс увидеть stale data.

roy ★★★★★
()

А можно-ли читать одни и те-же данные из одного и того-же буфера в двух разных потоках одновременно?

Да, конечно. Потокам, которые обязуются только читать данные («читатели»), нет смысла блокировать друг друга для чтения, поэтому они могут читать данные конкурентно.

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

Пока «писатель» модифицирует данные, «читатели» не могут к ним обращаться.

В POSIX Threads для этого есть свой набор функций и примитивов: http://www.daemon-systems.org/man/pthread_rwlock.3.html

Потоки-читатели должны использовать pthread_rwlock_rdlock() для доступа к данным, в то время, как потоки-писатели - pthread_rwlock_wrlock().

// Странно, что на это ещё никто не указал. Не узнаю ЛОР.

yoghurt ★★★★★
()

Главное, чтобы в процессе чтения данные не модифицировались.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от yoghurt

Потоки-читатели должны использовать pthread_rwlock_rdlock() для доступа к данным, в то время, как потоки-писатели - pthread_rwlock_wrlock().

О, я про эти функции не знал: для блокировок обычно пользовался только pthread_mutex_lock/pthread_mutex_trylock/pthread_mutex_unlock

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Можно подумать, pthread_rwlock_rdlock не использует pthread_mutex_lock…

Если бы именно ридерский pthread_rwlock_rdlock *всегда* использовал pthread_mutex_lock, у нас читатели блокировали бы друг друга.

yoghurt ★★★★★
()
Ответ на: комментарий от Begemoth

Только STM?

Только compare and swap!

Имелся в виду именно контекст данного вопроса, а не синхронизации вообще.

yoghurt ★★★★★
()

есть метод чтения - при котором ненужны блокировки суть в том - что нежелательно в данной ситуации прочитать искаженные данные - тоесть те которые неокончательно изменены

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

ae1234 ★★
()
Ответ на: комментарий от roy

Блокировки не только для обеспечения корректности данных при чтении записи используются, но и как memory barrier.

И каким же образом они выступают, как memory barrier?

mv ★★★★★
()
Ответ на: комментарий от yoghurt

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

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от mv

Т.к. язык программирования не указан, то данное предложение верно для Java Memory Model. Как именно?

In essence, releasing a lock forces a flush of all writes from working memory employed by the thread, and acquiring a lock forces a (re)load of the values of accessible fields. While lock actions provide exclusion only for the operations performed within a synchronized method or block, these memory effects are defined to cover all fields used by the thread performing the action.

http://gee.cs.oswego.edu/dl/cpj/jmm.html

roy ★★★★★
()
Ответ на: комментарий от roy

Т.к. язык программирования не указан, то данное предложение верно для Java Memory Model. Как именно?

Т.к. язык программирования не указан, то нефиг ЯП-специфичное поведение распространять на всё подряд.

mv ★★★★★
()
Ответ на: комментарий от mv

Просвяти тогда, как это в случае С?

И каким же образом они выступают, как memory barrier?

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

roy ★★★★★
()
Ответ на: комментарий от roy

В Си вообще никаких барьеров нет. Есть барьер у компилятора, когда его просят не кэшировать переменные в регистрах, и барьеры у процессора, когда его просят завершить все операции чтения и/или записи в пайплайне. Блокировки барьерам ортогональны. Нет, ну может быть, что код примитива блокировки содержит машинную инструкцию, которая в качестве сайд-эффекта делает барьер, но полагаться на это совершенно нельзя. Инструкции, выполненяющие барьер сайд-эффектом, не только разные у разных производителей, но ещё и есть вариации в поколениях процессора от одной конторы.

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

mv ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.