![]() Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Критические секции
Во многих случаях при разработке многопоточных приложений возникает задача организации монопольного доступа к какому-либо ресурсу. Например, нам необходимо добавить запись в буфер и увеличить счетчик занятых элементов, причем эту операцию могут выполнять несколько потоков одновременно. Изменение буфера и счетчика это достаточно сложная и длинная операция, и выполнить ее атомарно с помощью Interlocked-функций мы не можем, а неатомарное выполнение может привести к повреждению данных при одновременной работе. Решить эту проблему может механизм, называемый критическая секция. Для использования критической секции мы должны, прежде всего, для каждого ресурса с монопольным доступом создать переменную типа CRITICAL_SECTION. Эта переменная должна быть инициализирована с помощью функции InitializeCriticalSection: VOID InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection // critical section ); В качестве параметра этой функции передается указатель на наш объект. Перед началом работы с ресурсом каждый поток должен вызвать функцию EnterCriticalSection: VOID EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection // critical section ); Завершив работу с ресурсом необходимо вызвать функцию LeaveCriticalSection: VOID LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection // critical section ); Объект критическая секция запоминает, какой поток захватил его, вызвав EnterCriticalSection. Если после этого другой поток попытается захватить тот же объект, то вызванная функция EnterCriticalSection увидит, что объект занят и переведет поток в состояние ожидания до тех пор, пока критическая секция не освободится. Вызвав функцию LeaveCriticalSection, поток освобождает критическую секцию, давая, тем самым, возможность выполнится (или захватить ее позднее) одному из ожидающих потоков. Забиваем Сайты В ТОП КУВАЛДОЙ - Уникальные возможности от SeoHammer
Каждая ссылка анализируется по трем пакетам оценки: SEO, Трафик и SMM.
SeoHammer делает продвижение сайта прозрачным и простым занятием.
Ссылки, вечные ссылки, статьи, упоминания, пресс-релизы - используйте по максимуму потенциал SeoHammer для продвижения вашего сайта.
Что умеет делать SeoHammer
— Продвижение в один клик, интеллектуальный подбор запросов, покупка самых лучших ссылок с высокой степенью качества у лучших бирж ссылок. — Регулярная проверка качества ссылок по более чем 100 показателям и ежедневный пересчет показателей качества проекта. — Все известные форматы ссылок: арендные ссылки, вечные ссылки, публикации (упоминания, мнения, отзывы, статьи, пресс-релизы). — SeoHammer покажет, где рост или падение, а также запросы, на которые нужно обратить внимание. SeoHammer еще предоставляет технологию Буст, она ускоряет продвижение в десятки раз, а первые результаты появляются уже в течение первых 7 дней. Зарегистрироваться и Начать продвижение Если поток, который уже захватил критическую секцию, попытается захватить её еще раз, то эта операция будет успешно выполнена. Однако в этом случае ему придется и освобождать эту критическую секцию столько же раз, сколько он ее захватывал, чтобы она вновь стала свободной для других потоков. Следует соблюдать осторожность при работе с несколькими критическими секциями, чтобы не создать возможность возникновения deadlock’ов. Рассмотрим два потока, которые захватывают критические секции A и B в разном порядке:
Легко видеть, что при таком порядке выполнения потоки блокируют друг друга. Для того, чтобы избежать такой ситуации лучше всего постараться использовать вместо двух критических секций одну. Если это не удается, нужно чтобы во всех случаях использования нескольких критических секций они захватывались всегда в одном порядке (например всегда сначала А, потом В). Когда критическая секция нам будет больше не нужна, нужно освободить используемые ей системные ресурсы, вызвав функцию DeleteCriticalSection: VOID DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection // critical section ); Таким образом, обычный порядок работы с критической секцией выглядит следующим образом: // создаем переменную - критическую секцию CRITICAL_SECTION cs;
void main(void) { // перед началом работы инициализируем критическую секцию InitializeCriticalSection(& cs);
// работа программы
// в конце освобождаем ресурсы
DeleteCriticalSection(& cs); } … DWORD WINAPI SomeThreadProc(LPVOID Param) { … // в функции потока используем критическую секцию EnterCriticalSection(& cs);
// работаем с защищенным ресурсом в монопольном режиме
// освобождаем критическую секцию LeaveCriticalSection(& cs); … } Основной проблемой использования функции EnterCriticalSection является то, что ей нельзя указать время ожидания, и она может заблокировать поток на бесконечно долгое время. В Windows не предусмотрено функции, которая бы позволяла ожидать освобождения критической секции установленное время, однако есть функция, которая позволяет проверить, свободна или занята критическая секция. Это функция TryEnterCriticalSection: BOOL TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection // critical section ); Если критическая секция занята, то функция немедленно вернет значение FALSE. Если же критическая секция свободна, то TryEnterCriticalSection захватывает критическую секцию и возвращает TRUE (в этом случае можно сразу начинать использовать защищенный ресурс, вызвать EnterCriticalSection не надо). Сервис онлайн-записи на собственном Telegram-боте
Попробуйте сервис онлайн-записи VisitTime на основе вашего собственного Telegram-бота:— Разгрузит мастера, специалиста или компанию; — Позволит гибко управлять расписанием и загрузкой; — Разошлет оповещения о новых услугах или акциях; — Позволит принять оплату на карту/кошелек/счет; — Позволит записываться на групповые и персональные посещения; — Поможет получить от клиента отзывы о визите к вам; — Включает в себя сервис чаевых. Для новых пользователей первый месяц бесплатно. Зарегистрироваться в сервисе
|