Реализация барьера (конструкции синхронизации) с использованием двоичного семафора

Барьер - это конструкция синхронизации, в которой набор процессов синхронизируется глобально, то есть каждый процесс в наборе достигает барьера и ожидает прибытия всех остальных, а затем все процессы покидают барьер. Пусть количество процессов в наборе равно трем и S будет двоичным семафором с обычными функциями P и V. Рассмотрим следующую реализацию барьера на языке C с номерами строк, показанными слева.

void barrier (void) {    
    1: P(S);
    2: process_arrived++;
    3: V(S);
    4: while (process_arrived !=3);
    5: P(S);
    6: process_left++;
    7: if (process_left==3) 
       {
         8: process_arrived = 0;
         9: process_left = 0;
    10: }
    11: V(S);
 }

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

Будет ли работать вышеуказанная реализация? Я думаю, что это может привести к тупиковой ситуации, если два вызова барьера используются в непосредственной последовательности, поскольку первый процесс для входа в барьер не ждет, пока process_arhibited станет нулем, прежде чем приступить к выполнению P (S).


person Community    schedule 04.11.2011    source источник
comment
Что ж. Если мы предположим, что семафор был инициализирован до 1 перед вызовом барьера (), все 3 потока должны перейти к неприятному вращению на 4, если количество процессоров меньше 3 и приоритет первого потока / s, чтобы прибыть, выше чем более поздний, и в этом случае система будет заблокирована. Если 3 все же удается появиться в цикле, один получит блокировку на 5 и пройдет через него, установив process_left в 1, но оставив process_arhibited в 3. Затем он может освободить семафор, выполнить что-то, зацикливаться. снова вызовите барьер () и установите для параметра process_arhibited значение 4 ....   -  person Martin James    schedule 04.11.2011
comment
Ни один поток не должен покидать барьер, пока все потоки не будут в нем, тогда все потоки должны покинуть барьер, прежде чем какой-либо поток снова сможет войти.   -  person Martin James    schedule 04.11.2011
comment
Тогда есть проблема с глобальными переменными ...   -  person Martin James    schedule 04.11.2011
comment
Спасибо, Мартин. Поможет ли проверка значения process_arhibited перед входом и проверка значения process_left перед выходом решить эту проблему?   -  person    schedule 04.11.2011
comment
Это может быть поздно, но у меня есть вопрос: если 2 процесса работают одновременно, тупиковой ситуации может и не быть, но затем приходит третий процесс и ждет 4 неопределенно долго, потому что до сих пор process_arhibited = 2. Я прав?   -  person Soumyajit    schedule 10.02.2014


Ответы (2)


Хм ... ограничено тремя потоками и только двоичными семафорами, я бы хотел попробовать это с помощью трех семафоров, A, B, C. A контролирует доступ к счетчику process_arhibited, B и C предназначены для ожидания первого и второго потоков на. A инициализируется значением 1, B и C - 0. Поток 1 получает A, предотвращая вход 2 и 3. Переключение на process_arhibited приводит к тому, что поток 1 включает процесс_прибывший, освобождает A и ожидает на B. Поток 2 получает A, а переключатель заставляет его включать process_arhibited, переключаться и, таким образом, отпускать A и ждать на C. Поток 3 получает A, а переключатель вызывает он должен сигнализировать B, сигнал C, установить process_arhibited в 0, сигнал A и продолжить.

Потоки 1 и 2 не могут проходить B и C, пока 3 не подаст им сигнал. Когда B / C сигнализирует 3, 1/2 может бежать, но не может вернуться назад и попасть в барьер, пока 3 не отпускают A, после чего барьер находится в правильном состоянии, чтобы снова действовать как барьер - A имеет счет 1, B и C имеют ноль, а process_arhibited - ноль.

person Martin James    schedule 04.11.2011

Упоминается, что есть 3 процесса. Пусть это будут P1, P2 и P3. Каждый процесс достигает барьера, то есть завершает свою первую часть кода. Следовательно, process_arhibited = 3. Теперь предположим, что P1 продолжает выполнение, покидает барьер и делает process_left = 1. Теперь предположим, что P1 снова немедленно вызывает барьерную функцию. На этом этапе process_arhibited = 4. P1 теперь ждет. Вскоре P2 покидает барьер, что делает process_left = 2. Теперь P3 покидает барьер, который делает process_left = 3. Условие «если» истинно, и теперь process_arhibited и process_left сбрасываются в 0. Мы знаем, что P1 ожидает. На этом этапе предположим, что P2 вызывает барьерную функцию, следовательно, process_arhibited = 1, и он ожидает. P3 вызывает барьерную функцию, следовательно, process_arhibited = 2. Все процессы достигли барьера, но, поскольку process_arhibited = 2, все процессы продолжают ждать. Отсюда тупик.

person Ujjwal Saini    schedule 29.12.2014
comment
Я вообще-то не знаю, как происходит тупик. Прокомментируйте, правильно ли я понял? - person Ujjwal Saini; 29.12.2014