![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Критические участки
Если более чем один поток используют общие данные (переменная, массив, запись файла), возможны искажения данных. Эти искажения возникают, если потоки выполняют запись значений в совместно используемую переменную. Если один поток использует критический ресурс, то другие потоки не должны его использовать, а должны быть переведены ОС в состояние блокировки.
Условный пример: Два потока имеют доступ к одному и тому же файлу. Рисунок 1 -7
Поток 1: открывает запись, пишет в поля 1-4, и его квант времени заканчивается. Поток 2: изменяет поля5-6, записывает изменения. Поток 1: из буфера пишет в базу, и изменения, сделанные потоком 2, уничтожаются. Другой, более наглядный и более простой пример: Два потока, переменная global: word; начальное значение переменной равно 100, каждый поток пытается увеличить значение переменной global на 1, следующим образом: For I: =1 to 10 do Begin Sleep(5); I: =global; I: =i+1; запись в ListBox1 I; Global: =I; end; Поток 2 также имеет: For I; =1 to 10 do Begin Sleep (2); I: =global; I: =i+1; запись в ListBox2 I; Global: =I; end; Будет ли в итоге global=120, если потоки стартуют одновременно?
Если поток 1 берет I: =102, прибавляет 1, будет 103, квант истек. Поток 2 берет I: =102, прибавляет 1, запишет 103, поток 1 запишет 103. в обоих случаях могут быть разные значения, единица потеряна! Простейшее решение – inc(global). Interlocked – функции. Для увеличения или уменьшения на единицу глобальных переменных типа long: InterlockedIncrement(I); InterlockedDecrement(I); Возвращают: 0 – при переходе через 1; положительное число, если результат больше 0; отрицательное число, если результат меньше 0. Обмен переменными: InterlockedExchange (LTarget, LValue); Обеспечивает правильное увеличение (уменьшение) глобальной переменной типа longint без использования критических секций или мьютексов. Общее решение: использование средств синхронизации операционной системы: - критических секций; - мьютексов (Mutex – mutually exclusive – взаимоисключающие); - семафоров. Требования к средствам доступа к критическим участкам: 1. В любой момент времени только один поток может находиться в критическом участке; 2. Ни один поток не должен находиться в критическом участке бесконечно долго; 3. Ни один поток не должен ждать бесконечно долго входа в критический участок; 4. Поток завершившийся (аварийно) в критическом участке, не должен блокировать вход в критический участок для других потоков. Пример 2: Сотрудничающие потоки – задача «поставщик-потребитель». Поток - поставщик создает порции данных для передачи (через линии связи), а поток - потребитель передает их. Для хранения сообщений используется совокупность (пул) буферов на одно сообщение. Рисунок 1 – 8 - Взаимодействие поставщика и потребителя
Поставщик и потребитель должны синхронизировать свои действия – поставщик может передавать сообщения, когда есть свободное буферы в очереди, потребитель – может получать сообщения, если очередь не пуста.
|