Разница между взаимным исключением и синхронизацией?
В чем разница между двумя?
Этот вопрос пришел мне в голову, потому что я обнаружил, что
Мониторы и замки обеспечивают взаимное исключение
Семафоры и условные переменные обеспечивают синхронизацию
Это правда?
Также во время поиска я нашел эту статью
Любые уточнения, пожалуйста.
2 ответа
Взаимное исключение означает, что только один поток может иметь доступ к общему ресурсу в любой момент времени. Это позволяет избежать условий гонки между потоками, получающими ресурс. Мониторы и замки обеспечивают функциональность для этого.
Синхронизация означает, что вы синхронизируете / упорядочиваете доступ нескольких потоков к общему ресурсу.
Рассмотрим пример:
Если у вас есть две темы, Thread 1
& Thread 2
,Thread 1
а также Thread 2
выполнить параллельно, но до Thread 1
может выполнить сказать заявление A
в своей последовательности это обязательно, что Thread 2
должен выполнить заявление B
в своей последовательности. Здесь вам нужна синхронизация. Семафор обеспечивает это. Вы ставите semapohore ждать перед оператором A
в Thread 1
и вы публикуете в семафор после заявления B
в Thread 2
,
Это обеспечивает необходимую синхронизацию.
Лучший способ понять разницу с помощью примера. Ниже приведена программа для решения классической проблемы потребителя-производителя с помощью семафора. Чтобы обеспечить взаимное исключение, мы обычно используем двоичный семафор или мьютекс и для обеспечения синхронизации мы используем счетный семафор.
BufferSize = 3;
semaphore mutex = 1; // used for mutual exclusion
semaphore empty = BufferSize; // used for synchronization
semaphore full = 0; // used for synchronization
Producer()
{
int widget;
while (TRUE) { // loop forever
make_new(widget); // create a new widget to put in the buffer
down(&empty); // decrement the empty semaphore
down(&mutex); // enter critical section
put_item(widget); // put widget in buffer
up(&mutex); // leave critical section
up(&full); // increment the full semaphore
}
}
Consumer()
{
int widget;
while (TRUE) { // loop forever
down(&full); // decrement the full semaphore
down(&mutex); // enter critical section
remove_item(widget); // take a widget from the buffer
up(&mutex); // leave critical section
consume_item(widget); // consume the item
}
}
В приведенном выше коде переменная мьютекса обеспечивает взаимное исключение (разрешить доступ к критическому разделу только одному потоку), тогда как полная и пустая переменная используются для синхронизации (для доступа к общему ресурсу между различными потоками).