stringtranslate.com

Критический раздел

В параллельном программировании одновременный доступ к общим ресурсам может привести к неожиданному или ошибочному поведению, поэтому части программы, к которым осуществляется доступ к общему ресурсу, должны быть защищены способами, позволяющими избежать одновременного доступа. Один из способов сделать это известен как критический раздел или критическая область . В этот защищенный раздел не может войти более одного процесса или потока одновременно; другие приостановлены до тех пор, пока первый не покинет критическую секцию. Обычно критический раздел обращается к общему ресурсу, например к структуре данных , периферийному устройству или сетевому соединению, который не будет работать корректно в контексте множественного одновременного доступа. [1]

Потребность в критических разделах

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

Блок-схема, показывающая потребность в критическом разделе

Процесс А:

// Процесс А. . б = х + 5 ; // инструкция выполняется в момент времени = Tx .     

Процесс Б:

// Процесс Б. . х знак равно 3 + z ; // инструкция выполняется в момент времени = Tx .     

В тех случаях, когда запирающий механизм с более мелкой детализацией не требуется, важна критическая секция. В приведенном выше случае, если A необходимо прочитать обновленное значение x , одновременное выполнение процессов A и B может не дать требуемых результатов. Чтобы предотвратить это, переменная x защищена критической секцией. Сначала B получает доступ к разделу. Как только B закончит запись значения, A получит доступ к критической секции, и переменную x можно будет прочитать.

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

Реализация критических участков

Реализация критических разделов различается в разных операционных системах.

Критическая секция обычно завершается через конечное время [2] , и потоку, задаче или процессу придется ждать фиксированного времени, чтобы войти в нее ( ограниченное ожидание ). Для обеспечения эксклюзивного использования критических секций требуется некоторый механизм синхронизации при входе и выходе программы.

Критический раздел — это часть программы, требующая взаимного исключения доступа.

Блокировки и критические секции в нескольких потоках

Как показано на рисунке [3] в случае взаимного исключения ( мьютекса ), один поток блокирует критическую секцию, используя методы блокировки, когда ему необходимо получить доступ к общему ресурсу, а другим потокам приходится ждать своей очереди для входа. в раздел. Это предотвращает конфликты, когда два или более потоков используют одно и то же пространство памяти и хотят получить доступ к общему ресурсу. [2]

Псевдокод для реализации критической секции

Самый простой способ предотвратить любое изменение управления процессором внутри критической секции — реализовать семафор. В однопроцессорных системах это можно сделать, отключив прерывания при входе в критическую секцию, избегая системных вызовов, которые могут вызвать переключение контекста внутри секции, и восстанавливая прерывания в предыдущее состояние при выходе. Любой поток выполнения, входящий в любую критическую секцию в любом месте системы, при такой реализации не позволит любому другому потоку, включая прерывание, получить время обработки на ЦП — и, следовательно, от входа в любую другую критическую секцию или, более того, в любой код. что угодно — до тех пор, пока исходный поток не покинет свою критическую секцию.

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

Использование критических разделов

Критические разделы уровня ядра

Обычно критические секции предотвращают миграцию потоков и процессов между процессорами, а также вытеснение процессов и потоков прерываниями и другими процессами и потоками.

Критические секции часто допускают вложенность. Вложенность позволяет входить и выходить из нескольких критических секций с небольшими затратами.

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

Аналогично, если прерывание происходит в критическом разделе, информация о прерывании записывается для будущей обработки, а выполнение возвращается процессу или потоку в критическом разделе. [4] После выхода из критического раздела и, в некоторых случаях, завершения запланированного такта, ожидающее прерывание будет выполнено. Концепция квантового планирования применима к « циклическому » и аналогичным политикам планирования .

Поскольку критические секции могут выполняться только на том процессоре, на котором они введены, синхронизация требуется только внутри исполняющего процессора. Это позволяет входить и выходить из критических секций практически с нулевыми затратами. Межпроцессорная синхронизация не требуется. Необходима только синхронизация потока команд [5] . Большинство процессоров обеспечивают необходимую синхронизацию простым прерыванием текущего состояния выполнения. Это позволяет в большинстве случаев считать критические секции не более чем количеством введенных критических секций на процессор.

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

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

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

Критические разделы в структурах данных

В параллельном программировании код делится на потоки. Конфликтующие переменные чтения и записи распределяются между потоками, и каждый поток имеет их копию. Структуры данных, такие как связанные списки , деревья , хеш-таблицы и т. д., содержат переменные данных, которые связаны и не могут быть разделены между потоками, и, следовательно, реализация параллелизма очень сложна. [6] Чтобы повысить эффективность реализации структур данных, необходимо параллельно выполнять несколько операций, таких как вставка, удаление и поиск. При выполнении этих операций могут возникнуть ситуации, когда один и тот же элемент ищется одним потоком и удаляется другим. В таких случаях вывод может быть ошибочным . Поток, ищущий элемент, может иметь попадание, тогда как другой поток может удалить его сразу после этого. Эти сценарии вызовут проблемы в работе программы из-за предоставления ложных данных. Чтобы предотвратить это, один из методов заключается в том, что вся структура данных может храниться в критическом разделе, чтобы одновременно обрабатывалась только одна операция. Другой метод — заблокировать используемый узел в критическом разделе, чтобы другие операции не использовали тот же узел. Таким образом, использование критической секции гарантирует, что код обеспечивает ожидаемые результаты. [6]

Критические секции в отношении периферийных устройств

Критические разделы также встречаются в коде, который управляет внешними периферийными устройствами, такими как устройства ввода-вывода. Регистры периферийного устройства должны быть запрограммированы определенными значениями в определенной последовательности; если два или более процессов одновременно управляют устройством, произойдет некорректное поведение: ни один из процессов не приведет устройство в то состояние, которое ему требуется.

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

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

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

Смотрите также

Рекомендации

  1. ^ Рейналь, Мишель (2012). Параллельное программирование: алгоритмы, принципы и основы . Springer Science & Business Media. п. 9. ISBN 978-3642320279.
  2. ^ Аб Джонс, М. Тим (2008). Программирование приложений GNU/Linux (2-е изд.). [Хингем, Массачусетс] Charles River Media. п. 264. ИСБН 978-1-58450-568-6.
  3. Чен, Стенстрем, Гуанчэн, Пер (10–16 ноября 2012 г.). «Анализ критических блокировок: диагностика узких мест критических секций в многопоточных приложениях». 2012 Международная конференция по высокопроизводительным вычислениям, сетям, хранению и анализу . стр. 1–11. дои : 10.1109/sc.2012.40. ISBN 978-1-4673-0805-2. S2CID  12519578.{{cite book}}: CS1 maint: несколько имен: список авторов ( ссылка )
  4. ^ «ИССЛЕДОВАТЕЛЬСКИЙ ДОКУМЕНТ ПО ПРОГРАММНОМУ РЕШЕНИЮ ПРОБЛЕМЫ КРИТИЧЕСКОГО СЕЧЕНИЯ» . Международный журнал передовых технологий и инженерных исследований (IJATER) . 1 . Ноябрь 2011 г.
  5. ^ Дюбуа, Шойрих, Мишель, Кристоф (1988). «Синхронизация, когерентность и упорядочение событий в мультипроцессорах». Серия опросов и руководств . 21 (2): 9–21. дои : 10.1109/2.15. S2CID  1749330.{{cite journal}}: CS1 maint: несколько имен: список авторов ( ссылка )
  6. ↑ Аб Солихин, Ян (17 ноября 2015 г.). Основы параллельной многоядерной архитектуры . Тейлор и Фрэнсис. ISBN 9781482211184.

Внешние ссылки