Пожалуйста, объясните с точки зрения Linux, Windows?
Я программирую на C #, будут ли эти два термина иметь значение. Пожалуйста, постите как можно больше, с примерами и тому подобным ....
Спасибо
Пожалуйста, объясните с точки зрения Linux, Windows?
Я программирую на C #, будут ли эти два термина иметь значение. Пожалуйста, постите как можно больше, с примерами и тому подобным ....
Спасибо
Для Windows критические секции легче, чем мьютексы.
Мьютексы могут быть разделены между процессами, но всегда приводят к системному вызову ядра, которое имеет некоторые накладные расходы.
Критические разделы могут использоваться только в рамках одного процесса, но их преимущество заключается в том, что они переключаются в режим ядра только в случае конкуренции - неконтролируемые запросы, которые должны быть обычным делом, невероятно быстрые. В случае конфликта они входят в ядро, чтобы ожидать некоторый примитив синхронизации (например, событие или семафор).
Я написал быстрый пример приложения, в котором сравнивается время между ними. В моей системе для 1 000 000 несанкционированных приобретений и выпусков мьютекс занимает более одной секунды. Критическая секция занимает ~ 50 мс на 1000000 приобретений.
Вот тестовый код, я запустил его и получил аналогичные результаты, если мьютекс первый или второй, поэтому других эффектов мы не видим.
HANDLE mutex = CreateMutex(NULL, FALSE, NULL);
CRITICAL_SECTION critSec;
InitializeCriticalSection(&critSec);
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
LARGE_INTEGER start, end;
// Force code into memory, so we don't see any effects of paging.
EnterCriticalSection(&critSec);
LeaveCriticalSection(&critSec);
QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
EnterCriticalSection(&critSec);
LeaveCriticalSection(&critSec);
}
QueryPerformanceCounter(&end);
int totalTimeCS = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);
// Force code into memory, so we don't see any effects of paging.
WaitForSingleObject(mutex, INFINITE);
ReleaseMutex(mutex);
QueryPerformanceCounter(&start);
for (int i = 0; i < 1000000; i++)
{
WaitForSingleObject(mutex, INFINITE);
ReleaseMutex(mutex);
}
QueryPerformanceCounter(&end);
int totalTime = (int)((end.QuadPart - start.QuadPart) * 1000 / freq.QuadPart);
printf("Mutex: %d CritSec: %d\n", totalTime, totalTimeCS);
С теоретической точки зрения критический раздел - это фрагмент кода, который не должен выполняться несколькими потоками одновременно, поскольку код обращается к общим ресурсам.
Взаимная блокировка представляет собой алгоритм (а иногда и имя структуры данных) , который используется для защиты критических секций.
Семафоры и мониторы являются распространенными реализациями мьютекса.
На практике существует много реализаций мьютекса в Windows. В основном они различаются в результате своей реализации уровнем блокировки, областями их действия, стоимостью и эффективностью при разных уровнях конкуренции. См. CLR Inside Out - Использование параллелизма для масштабируемости для диаграммы затрат на различные реализации мьютекса.
Доступные примитивы синхронизации.
Оператор
lock(object)
реализован с использованиемMonitor
- см. MSDN для справки.В последние годы много исследований делается на неблокирующую синхронизацию . Цель состоит в том, чтобы реализовать алгоритмы без блокировки или без ожидания. В таких алгоритмах процесс помогает другим процессам завершить свою работу, чтобы процесс мог окончательно завершить свою работу. В результате процесс может завершить свою работу, даже если другие процессы, которые пытались выполнить какую-либо работу, зависают. Используя блокировки, они не снимают свои блокировки и не позволяют другим процессам продолжаться.
источник
В дополнение к другим ответам, следующие детали относятся к критическим разделам на окнах:
InterlockedCompareExchange
операцияВ Linux, я думаю, что они имеют «спин-блокировку», которая служит для целей, аналогичных критической секции с счетчиком спинов.
источник
Critical Section и Mutex не зависят от операционной системы, их концепции многопоточности / многопроцессорности.
Критическая секция - это фрагмент кода, который должен запускаться только самостоятельно в любой момент времени (например, одновременно запущено 5 потоков и функция «variable_section_function», которая обновляет массив ... вам не нужны все 5 потоков обновлять массив сразу. Поэтому, когда программа запускает crit_section_function (), ни один из других потоков не должен запускать свою критическую функцию_секции.
mutex * Mutex - это способ реализации кода критической секции (думайте о нем, как о токене ... поток должен обладать им, чтобы запускать критический_секционный_код)
источник
Мьютекс - это объект, который может получить поток, не позволяя другим потокам получить его. Это консультативный, а не обязательный; поток может использовать ресурс, который представляет мьютекс, не получая его.
Критическая секция - это длина кода, гарантируемая операционной системой, чтобы он не прерывался. В псевдокоде это будет выглядеть так:
источник
«Быстрый» Windows, равный критическому выбору в Linux, был бы futex , что означает быстрый мьютекс пространства пользователя. Разница между futex и mutex заключается в том, что с futex ядро включается только тогда, когда требуется арбитраж, поэтому вы экономите накладные расходы на общение с ядром каждый раз, когда изменяется атомный счетчик. Это может сэкономить значительное количество времени при согласовании блокировок в некоторых приложениях.
Футекс также может быть разделен между процессами, используя средства, которые вы бы использовали для совместного использования мьютекса.
К сожалению, фьютексы могут быть очень сложными для реализации (PDF). (Обновление 2018 года, они не так страшны, как в 2009 году).
Кроме того, это практически одинаково для обеих платформ. Вы делаете атомарные, управляемые токенами обновления для общей структуры таким образом, который (надеюсь) не вызывает голодания. То, что остается, - это просто метод достижения этого.
источник
В Windows критический раздел является локальным для вашего процесса. Мьютекс может быть общим / доступным для всех процессов. В основном, критические секции намного дешевле. Не могу комментировать Linux конкретно, но в некоторых системах они просто псевдонимы для одного и того же.
источник
Просто чтобы добавить мои 2 цента, критические разделы определяются как структура, и операции над ними выполняются в контексте пользовательского режима.
Тогда как мьютекс - это объекты ядра (ExMutantObjectType), созданные в каталоге объектов Windows. Операции мьютекса в основном реализованы в режиме ядра. Например, при создании Mutex вы в конечном итоге вызываете nt! NtCreateMutant в ядре.
источник
Отличный ответ от Майкла. Я добавил третий тест для класса мьютекса, представленного в C ++ 11. Результат несколько интересен и все еще поддерживает его первоначальное одобрение объектов CRITICAL_SECTION для отдельных процессов.
Мои результаты были 217, 473 и 19 (обратите внимание, что мое отношение времени для последних двух примерно сопоставимо с показателем Майкла, но моя машина по крайней мере на четыре года моложе его, так что вы можете увидеть свидетельства увеличения скорости между 2009 и 2013 годами). , когда XPS-8700 вышел). Новый класс мьютекса в два раза быстрее мьютекса Windows, но все же меньше, чем в десятую часть скорости объекта Windows CRITICAL_SECTION. Обратите внимание, что я тестировал только нерекурсивный мьютекс. Объекты CRITICAL_SECTION являются рекурсивными (один поток может вводить их повторно, при условии, что он выходит одинаковое количество раз).
источник
Функции AC называются реентерабельными, если они используют только свои фактические параметры.
Повторно входящие функции могут вызываться несколькими потоками одновременно.
Пример реентерабельной функции:
Пример не реентерабельной функции:
Стандартная библиотека C strtok () не является реентерабельной и не может использоваться двумя или более потоками одновременно.
Некоторые SDK для платформ поставляются с возвращающейся версией strtok (), называемой strtok_r ();
Энрико Мильоре
источник