LINUX.ORG.RU

взаимодействие потоков


0

0

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

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

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

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

>> мьютексами - неэффективно

>это почему?

в результате два читающих потока не смогут одновременно читать из памяти

generatorglukoff ★★
() автор топика

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

anonymous
()
Ответ на: комментарий от tailgunner

> А что такое "поток"? Это микрософтовский эвфемизм для термина "нить"?

поток (thread) - это общепринятое название схемы распараллеливания исполнения кода в пределах одного процесса. причём не только и не столько в мире Win32. впрочем, согласен, в минорных кругах всё ещё находит применение алиас термина "поток" под названием "нить".

> man pthread_rwlock_init

ack

// wbr

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

> Полагаю тебе могло бы подойти использования разделяемой памяти..

есть подозрение, что в многопоточной программе в пределах её потоков память и так как-бы эээ разделяемая ;) вопрос в том, какой выбрать механизм синхронизации для объекта, доступ к которому осуществляется преимущественно на чтение aka без модификации. как было подсказано выше, блокировки чтения/записи - rwlock - предназначены как раз для таких случаев.

// wbr

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

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

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

И на момент записи все остальные потоки будут точно так же ждать.

anonymous
()
Ответ на: комментарий от MiracleMan

>Однако, использование мьютексов считаю более универсальным подходом.

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

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

> Да, я понял, что в первом посте не закончил свою мысль. Однако, использование мьютексов считаю более универсальным подходом.

в каком плане - универсальную? и мьютексы и блокировки чтения/записи оба механизма на равных являются частью POSIX и, в том числе, поддерживаются glibc.

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

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

с POSIX блокировками на Linux есть одна маленькая особенность: это приоритеты на блокировку на чтение и на запись. по умолчанию aka с нулевыми атрибутами pthread_rwlock_init() создаёт блокировку, у которой чтение имеет приоритет над записью. это означает, что пока есть клиенты, которые держат блокировку на чтение, операция блокировки на запись будет ждать. при достаточно большом количестве запросов на чтение запросто можно достигнуть ситуации, при которой взять лок на запись будет практически невозможно aka pthread_rwlock_wrlock() будет висеть висеть и висеть. чтобы этого не произошло, при создании лока нужно явным образом указывать, что операция записи имеет приоритет над чтением:

pthread_rwlock_t lock;
pthread_rwlockattr_t attr;
pthread_rwlockattr_init(&attr);
pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
pthread_rwlock_init(&lock, &attr);

в этом случае операция записи имеет явным приоритет над чтением.

// wbr

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

> А ты попробуй использовать мьютексы совместно с семафорами... Примерно, как тут - http://doc.trolltech.com/qq/qq11-mutex.html

ps: by design POSIX семафоры предназначены для синхронизации в первую очередь не потоков но процессов через разделяемую память. это заметно более тяжеловесные объекты синхронизации, чем мьютексы или блокировки чтения/записи. смешивать в одну кучу мьютексы и семафоры IMHO явно не есть хорошо. тем более, что при желании межпоточный семафор легко реализуется поверх мьютекса.

// wbr

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

Ну, тут не стоило понимать написанное буквально.. Скорее, как пример возможной организации для получения нужной функциональности... В качестве ещё одного примера можно взять также rwsem (reader/writer semaphore) - http://www.linuxdriver.co.il/ldd3/linuxdrive3-CHP-5-SECT-3.html

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

> В качестве ещё одного примера можно взять также rwsem (reader/writer semaphore) - http://www.linuxdriver.co.il/ldd3/linuxdrive3-CHP-5-SECT-3.html

боюсь показаться назойливым, но указанные sema_init/up/down/etc - это API ядра и в user land оно неприменимо :)

// wbr

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

Да, разумеется.. Но, всегда есть возможность реализовать подобную функциональность самому, используя имеющиеся возможности.. Данные примеры приведены лишь как подтверждение и в качестве демонстрации данной возможности..

Честно говоря, на самом деле идея использования POSIX блокировок чтения и записи, достаточно неплоха.. Просто, в самом начале это как-то не пришло мне в голову.. :-)

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

>есть подозрение, что в многопоточной программе в пределах её потоков память и так как-бы эээ разделяемая ;)

угу, такая же разделяемая, как мозг при раздвоении личности :))) одна личность думает, вторая запоминает - и все это делается в один моцк :))

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