Синхронизация
Может быть двух видов:
1. Данные передаются по значению
2. По фронту (отловил сам факт изменения, а как оно изменилось – не важно)
По очереди сообщений мы воспринимали по фронту (сообщение пришло), и по значению (сообщение пришло с данными)
Проблема: лёгкость программирования и быстродействие, пока взаимодействуют две программы. Когда много процессов взаимодействуют, у нас возникает:
· Процессы синхронизируются друг с другом по четко оговоренной схеме (первый-второй)
· Процессы синхронизируются в режиме конкуренции
Жду события (тебе пора начинать работать, узнаю об этом по фронту) – действую – генерирую событие (запускает следующего, а я перехожу в режим ожидания)
Параллелизма нет, есть псевдопараллелизм, потому что всё идет по шагам.
В результате программы становятся сложными, трудно отлаживаемыми.
Программное обеспечение SolidWorks. При выполнении некоторых действий программа открывает 65 потоков, но нагрузка на 1 процессор.
Режим конкурирующего программирования более правильный. У нас есть потоки, которые конкурируют за некоторый виртуальный ресурс (не обязательно выражен физически). Виртуальным ресурсом есть возможность поработать над ресурсом в одиночку.
Потоки
Проблемы:
· Как можно это запрограммировать (техническая)
· Могу ли я его запрограммировать неправильно и к чему это проведет (научная)?
o Я неправильно запрограммировал доступ и оба процесса считают, что объект занят и никто не получает доступ
o Я неправильно запрограммировал доступ и оба процесса считают, что объект свободен и оба получают доступ
o Я так запрограммировал, что доступ к нему получает только один процесс, который до ресурса добрался первым, будет использовать его, пока ему не надоест.
У меня есть в разделяемой памяти переменная флаг = 0
Sharememory: int flag = 0;
//0 – свободная, 1 – занята
while(1)
{
while(flag)
{
flag = 1;
действие
flag = 0;
}
}
Если я таким образом запрограммирую два процесса, то на самом деле это неправильно запрограммированная конкуренция. Мы оставили 4 машинные команды и очень маленькая вероятность того, что вторая переменная сможет перехватить.
На одноядерных машинах эта вероятность уходит вообще (каждые 10000 машинных команд)
Ещё возможна проблема, когда ресурс не один, а их два. Когда ресурса два, то программы должны устанавливать два раза конкуренцию. Когда он получает оба ресурса, он выполняет свои действия. Но весело получается, когда одна программа захватила один ресурс (х), а другая программа (у). Каждый процесс забирает ресурс и не отдаёт его и получается клинч (два процесса забрали ресурсы и не отдают никому, помогает только перезагрузка).
Необходимо обнаружить клинч на стадии проектирования
Решения проблемы:
1. Псевдопараллелизм.
2. Промаркировать ресурсы, выдать каждому логический номер и при программирования любой задачи, нужно захватывать их от младших к старшим, а освобождать от старших к младшим.
3. Методы, основанные на понимании глубинной сути задачи (для каждого класса задач есть своя оптимизация).
У нас есть некоторые объекты, которые обладают некоторыми свойствами.
Есть книги, в которых есть рассказы. Но книги разные и рассказы разные, а иногда рассказы повторяются, иногда не повторяются. Мы хотим пойти в поход и взять полное собрание О. Генри. Надо собрать не просто рюкзак, а самый лёгкий рюкзак.
Юра: А вы знали, что после прорыва канализации над дата-центром, можно вызвать спецов IBM, которые будут тряпочками протирать гавно с серверов?
Чепелев: Если надо, они его языком будут слизывать, но это дороже.
while(flag != some)
{
flag = ”stop”;
...
flag = “some”;
}
Языки высокого уровня – это математическая модель, из нее генерируется исходный код. Не стоит воспринимать язык высокого уровня как исходный код.
xxx: mov ax, flag
mov bx, some
cmp ax,bx
jne xxx
mov cx, stop
mov flag, cx
...
mov cx, some
mov flag, cx
6 машинных команд от момента чтения флага до записи нового значения в память. Но в любом моменте может произойти аппаратное прерывание, которое остановит работу программы.
Если у нас две программы работают в конкурирующем режиме и выполняют этот блок кода и одна переменная вошла в ступор, вторая начинает отрабатывать и перетирает flag, а значения остались старые, то программа №1 больше не анализирует данные и работает со старыми.
Общие переменные категорически не рекомендуются!
Лабораторная работа №3 (задание)
1. Мысленно проанализировать текст программы, найти все косяки лабораторной работы №1 и описать их
a. У нас есть два писателя и один читатель и два писателя работают одновременно
b. Один читатель и один писатель
2. Найти алгоритм Петерсона для двух конкурентов (в Википедии правила Петтерсона, но не алгоритм) и внедрить в свою программу
3. Выучить теорию Петерсона (как выглядел бы алгоритм Петерсона на троих)