синхронизация потока Linux

Я плохо знаком с потоками Linux и Linux. Я провел некоторое время, гугля, чтобы попытаться понять различия между всеми функциями, доступными для синхронизации потока. У меня все еще есть некоторые вопросы.

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

  • gcc атомарные операции
  • futexes
  • взаимные исключения
  • спин-блокировки
  • seqlocks
  • rculocks
  • условия
  • семафоры

Мой ток (но вероятно испорченный) понимание является этим:

семафоры являются широким процессом, включают файловую систему (фактически, я принимаю), и являются, вероятно, самыми медленными.

Futexes мог бы быть механизмом блокировки основы, используемым взаимными исключениями, спин-блокировками, seqlocks, и rculocks. Futexes мог бы быть быстрее, чем механизмы блокировки, которые основаны на них.

Спин-блокировки не блокируются и таким образом избегают контекста swtiches. Однако они избегают контекстного переключения за счет потребления всех циклов на ЦП, пока блокировка не выпущена (вращаясь). Они должны, только должен использоваться в многопроцессорных системах по очевидным причинам. Никогда не спите в спин-блокировке.

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

Атомарные операции являются самым быстрым синхронизирующим вызовом и вероятно используются во всех вышеупомянутых механизмах блокировки. Вы не хотите использовать атомарные операции на всех полях в Ваших совместно используемых данных. Вы хотите использовать блокировку (взаимное исключение, futex, вращение, seq, rcu) или единственный атомарный opertation на флаге блокировки при доступе к нескольким полям данных.

Мои вопросы идут как это:

  1. Действительно ли я прав до сих пор с моими предположениями?

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

  3. Которые (если таковые имеются) блокировок предотвращают прерывание потока планировщиком или прерывают..., или я просто, идиот и все synchonization механизмы делают это. Какие виды прерывания предотвращены? Действительно ли я могу заблокировать все потоки или потоки только на потоке блокировки ЦП? Этот вопрос происходит от моего страха перед прерыванием потока, содержащего блокировку для очень наиболее часто используемой функции. Я ожидаю, что планировщик мог бы запланировать любое число других рабочих, которые, вероятно, столкнутся с этой функцией и затем блоком, потому что это было заблокировано. Большое контекстное переключение было бы потрачено впустую, пока поток с блокировкой не перенесен и заканчивается. Я могу переписать эту функцию для уменьшения времени блокировки, но тем не менее это так обычно называют, я хотел бы использовать блокировку, которая предотвращает прерывание... через все процессоры.

  4. Я пишу пользовательский код..., таким образом, я получаю программные прерывания, не аппаратные... право? Я должен избегать любых функций (spin/seq блокировки), которые имеют слово "irq" в них.

  5. Какие блокировки для записи ядра или кода драйвера и которые предназначены для непривилегированного режима?

  6. Кто-либо думает с помощью атомарной операции, чтобы иметь несколько перемещений потоков через связанный список, гаек? Я думаю к изменению atomicly текущий указатель объекта на следующий объект в списке. Если попытка работает, то поток может безопасно использовать данные, на которые указал текущий объект, прежде чем это было перемещено. Другие потоки были бы теперь перемещены вдоль списка.

  7. futexes? Какая-либо причина использовать их вместо взаимных исключений?

  8. Существует ли лучший путь, чем использование условия спать поток, когда нет никакой работы?

  9. При использовании gcc атомарной операции в секунду, конкретно test_and_set, я могу получить увеличение производительности путем выполнения не атомарного теста сначала и затем использования test_and_set для подтверждения? Я знаю, что это будет конкретным случаем, таким образом, здесь будет иметь место. Существует большое количество объектов работы, скажите тысячи. Каждый объект работы имеет флаг, который инициализируется к 0. Когда поток будет иметь эксклюзивный доступ к объекту работы, флаг будет тем. Будет много рабочих потоков. Любое время поток ищет работу, они не могут тест atomicly для 1. Если они читают 1, мы знаем наверняка, что работа недоступна. Если они читают нуль, они должны выполнить атомарный test_and_set для подтверждения. Таким образом, если атомарный test_and_set будет 500 циклами CPU, потому что он отключает конвейерную обработку, CPU причин для передачи и кэши L2 для сбрасывания/заполнения...., и простой тест является 1 циклом.... затем, пока у меня было лучшее отношение от 500 до 1, когда он пришел к спотыканию на уже завершенные объекты работы.... это будет победой.

Я надеюсь использовать взаимные исключения, или спин-блокировки к sparilngly защищают разделы кода, что я хочу только один поток в СИСТЕМЕ (не jsut ЦП) к доступу за один раз. Я надеюсь экономно использовать gcc атомарную операцию в секунду, чтобы выбрать работу и минимизировать использование взаимных исключений и спин-блокировок. Например: флаг в объекте работы может быть проверен, чтобы видеть, работал ли поток он (0=no, 1=yes или происходящий). Простой test_and_set говорит поток, если он имеет работу или потребности идти дальше. Я надеюсь использовать условия разбудить потоки, когда существует работа.

Спасибо!

5
задан johnnycrash 7 April 2010 в 18:25
поделиться

4 ответа

относительно вопроса № 8 Есть ли лучший способ, чем использование условия для приостановки потока, когда нет работы? {{1} } да, я думаю, что лучший подход вместо использования сна - это использование таких функций, как sem_post () и sem_wait из "semaphore.h"

с уважением

0
ответ дан 15 December 2019 в 00:55
поделиться

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

  • Программирование потоков Pthread: стандарт POSIX для улучшенной многопроцессорной обработки

и

  • Программирование с помощью потоков POSIX (R)
0
ответ дан 15 December 2019 в 00:55
поделиться

Замечание о фьютексах - они более описательно называются быстрыми мьютексами в пользовательском пространстве . В случае фьютекса ядро ​​задействуется только тогда, когда требуется арбитраж, что обеспечивает ускорение и экономию.

Реализация фьютекса может быть чрезвычайно сложной (PDF), их отладка может привести к безумию. Если вам действительно, очень, очень не нужна скорость, обычно лучше использовать реализацию мьютекса pthread.

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

0
ответ дан 15 December 2019 в 00:55
поделиться

Код приложения, вероятно, должен использовать функции потоков posix. Я предполагаю, что у вас есть справочные страницы, поэтому наберите

man pthread_mutex_init
man pthread_rwlock_init
man pthread_spin_init

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

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

2
ответ дан 15 December 2019 в 00:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: