12. Основные примитивы синхронизации потоков
В одном процессе может выполняться сколько угодно потоков, а если есть несколько потоков, то их нужно синхронизировать.
int n=0, f=0;
while (1) {          while (1) {
    while (!f);          while (f);
    n++, n++;            if (n…)
    f=0;}                f=1;
Минусы данной синхронизации:
- 
    
впустую тратится энергия и процессорное время
 - 
    
если переменных больше одной, то возникнут трудности
 
При выполнении параллельных процессов может возникать проблема, когда каждый процесс, обращающийся к разделяемым данным, исключает для всех других процессов возможность одновременного с ним обращения к этим данным - это называется взаимоисключением
Поэтому современные ОС содержат такое понятие mutex (взаимное исключение) это позволяет чтобы потоки выполнялись непрерывно – это обычный флажок.
С mutex возможны 2 операции: lock(m)- заблокировать и unlock(m)- разблокировать. Это обуславливает поочередный доступ к общему ресурсу.
Mutex – это частный случай «Семафора». В основе семафора – счетчик n.
При каждом захвате из счетчика вычитается 1, когда станет 0 – следующий захват заблокирует всех. «Семафор» нужен для защиты однородных ресурсов. Таким образом, синхронизация решается методом поочередной блокировки с помощью семафора и mutex.
Не все виды синхронизации решаются данным способом, поэтому существует второй вид – синхронизация по времени (должно произойти некоторое событие, которого дожидается программа). Для этого используется «условная переменная» q-war (Unix), event (Windows). С этим понятием можно использовать две операции: wait (E)- ждать сигнал и Signal (E)- послать сигнал, причем события не гарантируют, что потоки не проспят сигнал.