В чем разница между мьютексом и критическим разделом?

public int year;

public void setYear(String year){
   try {
      year = Integer.parseInt(year);
   } catch(Exception e) {
       e.printStackTrace();
   }
}

Вы можете использовать try и catch, чтобы проверить, является ли ввод числа. Здесь вы пытаетесь разобрать строку в целое число. Если он содержит только число, он сможет успешно преобразовать его. С другой стороны, если у него есть другие символы, он остановится, и вы получите исключение. Try and catch предотвращает сбой вашей программы.

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

String regex = "[0-9]+";
year.matches(regex );
130
задан 6 July 2012 в 09:52
поделиться

8 ответов

Для 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);
222
ответ дан 24 November 2019 в 00:21
поделиться

Критическая секция и Mutex не зависят от операционной системы, их концепции многопоточности / многопроцессорности.

Критический раздел Это фрагмент кода, который должен выполняться только самостоятельно в любой момент времени (например, одновременно запущено 5 потоков и функция называется «crit_section_function», которая обновляет массив ... вы не хотите, чтобы все 5 потоков обновляли сразу за массивом. Поэтому, когда программа запускает crit_section_function (), ни один из других потоков не должен запускать свою функцию критической_секции.

mutex * Mutex - это способ реализации кода критической секции (думайте о нем, как о токене ... поток должен обладать им, чтобы запускать критический_секционный_код)

18
ответ дан 24 November 2019 в 00:21
поделиться

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

  • в отсутствие конфликта, получение критического раздела так же просто, как InterlockedCompareExchange Операция
  • Структура критического сечения вмещает мьютекс. Первоначально он не выделяется
  • , если между потоками для критического раздела существует конфликт, мьютекс будет выделен и использован. Производительность критической секции будет ухудшаться до производительности мьютекса
  • , если вы ожидаете высокую конкуренцию, вы можете выделить критическую секцию, указав число спинов.
  • Если есть конфликт в критической секции с числом спинов, поток, пытающийся получить критическую секцию, будет вращаться (занято-ждать) в течение такого количества циклов процессора.
21
ответ дан 24 November 2019 в 00:21
поделиться

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

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

Семафоры и Мониторы являются распространенными реализациями мьютекса.

На практике существует много реализаций мьютекса, доступных в окнах. Они в основном отличаются как следствие их реализации их уровнем блокировки, их областями действия, их стоимостью, и их производительность при разных уровнях раздора. См. CLR наизнанку - Использование параллелизма для масштабируемости для графика затрат на различные реализации мьютекса.

Доступные примитивы синхронизации.

Оператор lock (object) реализован с использованием монитора - см. MSDN для справки.

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

85
ответ дан 24 November 2019 в 00:21
поделиться

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

Критическая секция - это длина кода, гарантируемая операционной системой, чтобы он не прерывался. В псевдокоде это будет выглядеть так:

StartCriticalSection();
    DoSomethingImportant();
    DoSomeOtherImportantThing();
EndCriticalSection();
13
ответ дан 24 November 2019 в 00:21
поделиться

«Быстрый» Windows, равный критическому выбору в Linux, был бы futex , который обозначает быстрый мьютекс пространства пользователя. Разница между futex и mutex заключается в том, что с futex ядро ​​включается только тогда, когда требуется арбитраж, поэтому вы экономите накладные расходы на общение с ядром каждый раз, когда изменяется атомный счетчик. Это может сэкономить значительное количество времени согласования блокировок в некоторых приложениях.

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

К сожалению, фьютексы могут быть очень сложными для реализации (PDF). (Обновление 2018 года, они не так страшны, как в 2009 году).

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

14
ответ дан 24 November 2019 в 00:21
поделиться

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

6
ответ дан 24 November 2019 в 00:21
поделиться

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

ntdll!_RTL_CRITICAL_SECTION
   +0x000 DebugInfo        : Ptr32 _RTL_CRITICAL_SECTION_DEBUG
   +0x004 LockCount        : Int4B
   +0x008 RecursionCount   : Int4B
   +0x00c OwningThread     : Ptr32 Void
   +0x010 LockSemaphore    : Ptr32 Void
   +0x014 SpinCount        : Uint4B

Тогда как мьютекс - это объекты ядра (ExMutantObjectType), созданные в Каталог объектов Windows. Операции мьютекса в основном реализованы в режиме ядра. Например, при создании Mutex вы в итоге вызываете nt! NtCreateMutant в ядре.

6
ответ дан 24 November 2019 в 00:21
поделиться
Другие вопросы по тегам:

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