2016-05-25 2 views
-4

Я хочу проверить, действительно ли это так: когда конкретный поток находится внутри критического раздела, другие потоки программы, которые не находятся в критическом разделе, не могут быть выполнены?Является ли Windows CRITICAL_SECTION предотвращением выполнения другого потока

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

взгляните на этот URL: http://www.careerride.com/VC++-critical-section-mutex-and-semaphore.aspx это правда?

+0

Другие темы не могут одновременно вводить один и тот же CRITICAL_SECTION. Они не прекращают выполнение другого кода или вводят другие CRITICAL_SECTIONs –

+0

Если он правильно используется, критический раздел блокирует другие потоки, если они попытаются войти в критический раздел, пока поток уже находится в этом разделе. Таким образом, вы можете иметь только один поток, выполняющий код между входом и выходом из критического раздела. ОС переключится на другой поток, который не заблокирован. – Phil1970

+0

В редакции 17:09 UTC ссылка на карикатуру либо вводит в заблуждение, либо очень плохо сформулирована. Результат тот же, и я должен назвать это неправильным. – user4581301

ответ

2

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

Ваш вопрос в том, что вы хотите проверить работу потоков.

Мое объяснение будет сфокусировано на использовании среды Visual Studio, как вы уже спрашивали о критическом разделе Windows.

Имейте глобальную переменную int loop = 1; Имейте критический раздел, который имеет только код while (loop); (бесконечный цикл)

Имеет по меньшей мере 2 потока в программе. Запустите код в отладчике. Смотрите вид потоков в среде IDE, и вы увидите, что один поток просто застревает во время (цикл).

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

Теперь измените значение цикла на 0 из вида просмотра отладчика. И все же ничего не изменится, поскольку первая нить, содержащая критический раздел, была заморожена. Теперь просто поставьте точку прерывания в строке while (loop) и запустите замороженный поток, тогда вы увидите, что, поскольку мы изменили значение цикла на 0, поток, который удерживал критический раздел, выйдет из критического раздела.

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

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

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

0

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

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

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

I recommend giving this a read.

Я также рекомендую, если C++ 11 или более позднего стандарт является вариантом, используя <thread> library's взаимные исключения объектов, чтобы улучшить свою портативность.

2

Позвольте мне попытаться сделать это простым.

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

Если сигнал в Лондоне зеленый или красный, и вы ожидаете особого сигнала в Сан-Франциско - на самом деле не имеет значения, станет ли этот сигнал в Лондоне зеленым (вам не разрешат проходить). Ни лондонский сигнал не краснеет, что вы не можете пересечь сигнал.

Аналогичным образом, ни один из таких сигналов не предотвратит любые транспортные средства на скоростной автомагистрали. Другие транспортные средства не блокируются сигналом, который вы ожидаете (это свободные потоки в перспективе ОС).

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

Это CS и мьютексы. Если вы заблокированы EnterCriticalSection или WaitForSingleObject, вы ждете, что сигнальная лампа станет зеленой для вас (ожидающая нить).

Смежные вопросы