алгоритм состояния гонки - PullRequest
0 голосов
/ 24 января 2011

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

while (turn != mine);
critical_region();
turn = (1-mine);

Четко объясните любые возможные проблемы и ограничения с помощью этой второй альтернативы.

Я просто не получаю часть, "turn = (1-mine)", я имею в виду, изначально T1 войдет, поскольку "mine"1. когда он выйдет, ход все равно останется 0. поэтому T0, никогда не сможет войти в критическую область?

Ответы [ 2 ]

2 голосов
/ 24 января 2011

turn = (1-mine) относительно легко объяснить. Допустим, поток 0 (тот, где mine установлен на 0) имеет критическую секцию. Когда он закончится, он установит turn в 1 - mine или 1, чтобы запустить другой поток.

Когда поток 1 (тот, где mine установлен на 1) имеет критическую секцию. Когда он закончится, он установит turn в 1 - mine или 0, что позволит запустить другой поток.

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

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

Например, предположим, что поток 0 завершил работу с токеном, поэтому для turn установлено значение 1. Но поток 1 отключен для выполнения интенсивных вычислений, и не требуется токен прямо сейчас.

Но потоку 2 нужен токен, так как он хочет выполнить некоторую работу над критическим разделом. Он должен ждать, пока поток 1 не передаст ему токен, не очень хорошая ситуация.

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

0 голосов
/ 24 января 2011

просто не получить часть, "turn = (1-mine)", я имею в виду, изначально T1 войдет, потому что "mine" равно 1. Когда он выйдет, ход все равно останется 0. Так T0, выигралВы никогда не сможете войти в критическую область?

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

while (turn != mine)
    ; //spin
critical_region();
turn = (1-mine);

Итак, важно отметить, что когда turn == mine, поток продолжит и выполнит вычисления.

Итак, давайте назовем наши потоки T0 и T1.

Когда T0 завершится,что будет turn будет установлено?

Когда T1 закончится, что будет turn установлено?

...