Для синхронизации действий, выполняемых разными потоками существует несколько различных способов. Условно их можно разделить на следующие:
· синхронизация с помощью глобальных переменных
· синхронизация с помощью обмена событиями
· синхронизация с помощью специальных объектов (событий, семафоров, критических секций, объектов исключительного владения и других)
Первый метод синхронизации следует признать самым неудачным, так как он требует постоянного опроса состояния глобальной переменной. У этого метода есть и более серьезные недостатки — так, например, возможна полная блокировка потоков, если поток, ожидающий изменения глобальной переменной имеет более высокий приоритет, чем поток, изменяющий эту переменную. Правда, его можно несколько улучшить — вводя дополнительные временные задержки между последовательными опросами.
Второй метод потребует создания объектов, способных получать сообщения или извещения о выполнении некоторых действий. Это могут быть окна, файлы (например, при использовании асинхронных операций или операций с уведомлением), каталоги и т.д. Во многих случаях может быть удобно создать невидимое окно, участвующее в обмене сообщениями или ожидающее получения сообщений для выполнения тех или иных действий.
Третий метод — синхронизация с помощью специальных объектов — потребует рассмотрения разных объектов и разных методов синхронизации с использованием объектов. В Win32 API существует большое число объектов, которые могут быть применены в качестве синхронизирующих, причем во многих случаях вместо одного объекта может применяться объект другого типа. Поэтому будет интересно рассмотреть несколько основных методов синхронизации с использованием объектов.
При рассмотрении способов синхронизации удобно выделить несколько основных способов, применяемых разными операционными системами. В числе таких способов можно выделить четыре метода:
· критические секции
· объекты исключительного владения
· события
· синхронизация группой объектов
Последовательно рассмотрим эти основные методы, используя в качестве примера функции по работе с глобальной кучей. Попробуем абстрактно разобраться со свойствами этих функций, что бы понять, какие методы синхронизации и в каких случаях удобно применять.
Во–первых, глобальную кучу в целом можно рассматривать как некий сложный объект, над которым могут выполняться некоторые операции (пока мы рассматриваем только операции над кучей в целом, не вдаваясь в нюансы работы с отдельными блоками — при необходимости доступ к отдельным блокам кучи должен быть синхронизирован, но это уже не функции кучи, а проблема того, кто пользуется кучей).
Часть операций, например получение указателя на какой–либо блок в куче, не нуждается в изменении самой кучи. То есть функции, осуществляющие подобные операции могут выполняться одновременно разными потоками не конфликтуя друг с другом. Такие функции удобно назвать “читателями” — они не изменяют кучу как единый объект.
Другие операции, например выделение нового блока в куче, требуют внесения изменений в кучу — изменения в цепочке выделяемых блоков. Обычно такие изменения осуществляются не в одном месте, а требуется согласованное внесение изменений в нескольких структурах данных. В процессе такой операции структура кучи какое–то время оказывается нарушенной, вследствие чего одновременное выполнение таких действий должно быть исключено. Такие функции удобно назвать “писателями” — они изменяют кучу как единый объект.
Применительно к куче возможен одновременный доступ нескольких читателей и исключительный — писателей. Более того, если к куче получает доступ писатель, то читатели также должны быть лишены доступа (в других случаях это может быть не так — читатели могут работать одновременно с писателем).
Можно сформулировать несколько правил для работы с таким объектом:
· если к объекту имеет доступ писатель, то ни читатели, ни другие писатели доступа не имеют;
· если к объекту имеет доступ читатель, то возможен одновременный доступ других читателей и запрещен доступ писателям;
· если объект свободен, то первый пришедший писатель или читатель имеет право доступа.
Рассмотренный пример очень удобен, так как подобная ситуация (много читателей, единственный писатель) встречается сплошь и рядом — а стандартного объекта для синхронизации доступа к такому объекту нет. Благодаря этому такой пример становится благодатной почвой для рассмотрения разных способов синхронизации.
|
Номер | Поток, уже имеющий доступ | Поток, требующий доступа | Действие |
| 1 | читатель | читатель | разрешить доступ |
| 2 | читатель | писатель | ожидать освобождения[1] |
| 3 | писатель | читатель | ожидать освобождения[1] |
| 4 | писатель | писатель | ожидать освобождения |
| 5 | — | читатель | разрешить доступ |
| 6 | — | писатель | разрешить доступ |
Даже при простейшем анализе такой таблицы можно заметить, что писатели н
Наверняка у вас есть товары или услуги, продажа которых приносит вам максимальную прибыль. Для быстрого старта в сети вам необходимо создание посадочной страницы (одностраничного сайта), на которой будет размещена информация о маржинальных товарах/услугах интернет магазина. За 8 лет опыта разработки конверсионных страниц мы выработали оптимальную структуру, которая позволит привлекать через landing page больше продаж. На такую структуру «одевается» ваш контент — фирменный стиль, тексты, фотографии, уникальные торговые предложения, после чего страница выходит в свет. Разработка лендинга и запуск в сети — до 7 рабочих дней. Стоит отметить, что в разработку самой посадочной страницы входит и написание копирайтером продающих текстов для вашего бизнеса, чтобы каждый посетитель страницы захотел совершить покупку именно у вас. Результат: качественно разработаная продающая посадочная страница, которая готова приносить вам новых клиентов.