Лучший способ разобраться в различиях с помощью примера. Это программа для решения классической проблемы потребителя-производителя через семафор. Для обеспечения взаимного исключения мы в основном используем двоичный семафор или мьютекс, а для обеспечения синхронизации мы использовать счетный семафор.
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
}
}
В приведенном выше коде переменная мьютекс обеспечивает взаимное исключение (разрешить только один поток, чтобы получить доступ к критической секции), тогда как полный и пустой переменной используются для Synchonization (для aribtrate доступа общего ресурса среди различных ниток).