Последнее время довольно много приходится работать с потоками. И привычный Synchronize начинает раздражать. Поискав в инете нашёл TCriticalSection - показалось, что вот решение проблем. Обычно делаю так:
With TCriticalSection.Create Do Begin Enter; //Do some action Leave; Free; End;
Какова применимость такого подхода?
Подойдёт ли он для, скажем, записи в лог-файл, или WriteLn?
Можно ли таким образом обрабатывать большые списки с которыми работают остальные потоки, с кучей обращений к БД и времени исполнения в несколько секунд?
Обращаться в основной поток, например для того же изменения гуя, что часто приводят в пример для Synchronize?
Критическая секция должна существовать все время, пока существует разделяемый объект. Создать её и тут же грохнуть? А если парараллельно кто-то еще хочет обратится к разделяемому объекту, то он свою критическую секцию создаст? Себе родному? Смысл в том, чтобы у одной и той же критической секции из разных потоков просить доступ к объекту, который в общем пользовании. Насчет окошек, то синхронизе - лучший вариант. Можно, конечно конву блокировать, но это отдельная песня для программ, которые рисуют на канве, а не вообще для интерфейсных элементов.
With TCriticalSection.Create Do Begin Enter; //Do some action Leave; Free; End;
не имеет смысла.
Нужно, что бы все потоки, которые обращаются к разделяемому ресурсу, обращались к одному и тому же экземпляру критической секции. Т.е. где то нужно создать экземпляр
Что ж тут неясного, доступ запрещен. А остальное - это можете только вы сами в дебагере отыскать.
Скорее всего, Вы просто не понимаете принцип использования критических секций. Есть очень хорошая статья на "Королевстве", почитайте.
Но если коротко, то критическая секция формируется через обращение к ячейке, для которой операция "проверка значения и запись при нулевом значении" будет атомарна - то есть неразделима в многопроцессной среде. Фактически, это как железнодорожная стрелка - все подошли с разных сторон, если стрелка свободна, то дергают к себе. Кто-то был первым, стрелка включается к нему. Он свободно "входит в секцию" и делает свои дела. Когда выходит - стрелка освобождается. Кто-то другой может включить на себя. Пока стрелка занята, все подошедшие регулярно дергают рычаг стрелки на себя и ждут.
Проблема в том, что фактически такое включение - две операции - проверка состояния флага и его установка. Если атомарности не будет, то два процесса могут проверить флаг, а затем его установить одновременно. И войти в критическую секцию вместе. А сам код внутри критической секции будет, скорее всего, очень критичен к "однопоточности".
Прочитайте статью на "Королевстве Дельфи" и постройте для себя схему работы Ваших потоков - наверное где-то у Вас есть лишний выход из секции или ее удаление из памяти без освобождения, либо вход в секцию без создания...