Советы по Delphi

         

Рассуждения о потоках


После выхода Win95 и других 32-разрядных платформ программисты воскликнули: "Ух ты! Потоки!"

Да, в иногда они действительно дают великолепных результат. Но иногда кажется, что мультипотоковые приложения работают много медленней и требуют больше системных ресурсов, чем их эквивалентная реализация под Win31.

Итог: Умножение потоков не умножает CPU.

Если вы имеете более одного процессора, это замечательно. В противном случае множество параллельных потоков не ускоряет работу приложения, поскольку в отдельно взятый промежуток времени возможно выполнение только одного потока. Кроме того, чем больше у вас потоков, тем больше нагрузки на систему, потраченной на переключение между ними. Если ваш проект имеет более двух постоянно работающих потоков, то такая мультизадачность не сделает программу быстрее. Обратное же утверждение истинно!

Итог: Использование потоков для перекрытия обработки I/O.

В этом случае нужно вначале понять для чего необходим поток. Поток, осуществляющий обработку, может проигнорировать необходимость системы быстро реагировать на I/O запросы. Сам же он может не реагировать на эти запросы, полностью доверив это операционной системе. Потоки позволяют программе отзываться на просьбы пользователя и устройств, но при этом (в том числе) сильно загружать процессор. Потоки позволяют компьютеру одновременно обслуживать множество устройств, и созданный вами поток, отвечающий за обработку специфического устройства, в качестве минимума может потребовать столько времени, сколько системе необходимо для обработки запросов всех устройств.

Итог: Расставляйте приоритеты потоков в зависимости от задач.

Потокам можно назначить определенный приоритет для того, чтобы наименее значимые процессы выполнялись в фоне. Это путь честного разделения ресурсов CPU. Просто необходимо осознать тот факт, что процессор один на всех, а потоков, эдаких "мальчиков на побегушках" ну очень много. Если в вашей программе главная процедура передает нечто для обработки в низкоприоритетный поток, то сама программа становится просто неуправляемой.

Итог: Конкуренция за обладание ресурсами.

Потоки хорошо работают когда они независимы. Но они начинают работать непродуктивно (становятся не лучше (а может быть хуже) чем очередь системных сообщений), когда они вынуждены синхронизироваться для доступа к общим ресурсам. Блокировка и критические секции отнюдь не добавляют бодрости системе.

Итог: Борьба за пользовательский интерфейс.

Один из наиболее горячо оспариваемых ресурсов в системе - интерфейс пользователя. В конце концов, сама Windows представляет собой набор высокоприоритетных задач, являющихся вашими прямыми конкурентами и наравне с вами лезущими в драку за обладание ресурсами. И если несколько потоков одновременно попытаются обновить одно и то же окно, то визуальный хаос вам обеспечен.

Итог: Управляйте нагрузкой... если есть инструмент для этого.

Слишком много потоков - и Windows становится похожей на умирающего лебедя. Это вызывает нарушения и нестабильную работу. Вы не можете создать поток просто "по просьбе пользователя" и надеяться, что Windows его обслужит в первую очередь. Так не будет. Для эффективного управления и нормальной продуктивности вы должны контролировать поступающую нагрузку, отслеживать текущее состояние компьютера и варьировать приоритетами.

Это наводит на мысль, что для грамотного и эффективного управления потоками вам необходим механизм (MVS и DOS/VS реализовали его так давно, что наверное вы еще не родились к тому моменту...), или "монитор транзакций", или другие части программного обеспечения, встраиваемые в ваше приложение и позволяющие организовывать очереди и регулировать рабочие потоки для многопользовательского или серверного режима.

Помните также, что "процесс, который не может быть реально завершен в режиме параллельной работы... ему необходим не отдельный поток, ему необходима очередь сообщений."

Итог: Помните, что память виртуальна.

Механизм виртуальной памяти следит за тем, какая "часть памяти" должна находиться в RAM, а какая должна быть сброшена в файл подкачки. Потоки усложняют ситуацию, если они обращаются в одно и то же время к разным адресам виртуальной памяти. Это значитель увеличивает нагрузку на систему. Помните, что реально память не всегда "свободна", как это пишут в окошках "О системе". Всегда отождествляйте доступ к памяти с доступом к файлу на диске и создавайте приложение с учетом вышесказанного.

Итог: Заявляйте о себе открыто.

Всякий раз, когда любой из ваших потоков пытается воспользоваться общим ресурсом, вы обязаны каким-то образом легализовать и защитить вашу деятельность. Хорошим средством для этого являются критические секции, семафоры и очереди сообщений. Если вы протестировали ваше приложение в "стерильном" режиме и не напоролись ни на одну из ошибок синхронизации, то знайте, в реальном режиме, когда пользователю вздумается запустить что угодно, вы попадете впросак, ибо ошибки будут обязательно!

Итог: Делегируйте обязанности, все время.

Итак, вы должны предусмотреть многочисленный доступ множества потоков к общим ресурсам. Хорошей идеей в данном случае является делегирование функций доступа специализированным потокам, специально создаваемым для этих целей, умеющим создавать очереди, работать в дискретном режиме с определенным кругом устройств и иметь небольшой набор обязанностей, с которыми они отлично справляются. Это лучшее решение, чем поток, похожий на "царя горы", способный заблокировать множество других автономных задач.

[000261]



Содержание раздела