Доброго времени суток! Начинаю постигать премудрости многопотокового программирования. Продолжаю писать прогу: OPC сервер. При его запуске одновременно стартует поток, внутри него стоит бесконечный цикл (типа for( ;; )//мой код}) там где (//мой код) просходит опрос MODBUS устройств -> получение с них нанных -> обновление тегов OPC сервера. ЭТО должно происходить постоянно!!! (т.е. опрос....обновление тегов) НО при этом процессор загружается на все 100%!!! Наверное есть стандартные алгоритмы работы для многопотоковых программ....сейчас Рихтера осваиваю...)))) Заранее спасибо, если кто-то поможет...
Нужно ждать на событиях, которые возникают когда что-то изменяется. События должен устанавливать драйвер соотвествующих устройств по прерываниям от них. Если устройства не поддерживают прерываний, то нужно менять устройства.
Чуть спасёт Код (Text): for ( ;; ) { Опрос устройства; if (Данных нету) { Sleep(1); /* переключим контекст */ continue; } Получение данных; Обновление тегов; }
Возможно не в тему, но все-таки интересно: Если у меня работают несколько тредов в одном процессе, нужно ли делать синхронизированный доступ (крит. секции, мьютексы) при чтении данных по одим адресам??? Или достаточно сделать только для записи?
Span Если у меня работают несколько тредов в одном процессе, нужно ли делать синхронизированный доступ (крит. секции, мьютексы) при чтении данных по одим адресам??? ______________________________________________________ Очень актуальный вопрос!!! Вот сейчас сижу и разгребаю....
Если чтение и запись атомарны, то не нужно. А если данные >4 байт, то нужно, иначе есть риск прочтения данных, в которых инварианты не выполняются.
А можно про "инварианты" пару слов? И где бы про это почитать? Реальный пример. Есть структура данных, общая для всех потоков. (там есть DWORDы, указатели на строки и другие структуры) Нужно ли доступ на чтение синхронизировать?
категорично так.. по теме: нужно, если какие-то другие потоки пишут в эти данные правда, если обращение к данным на чтение осуществляется за одну инструкцию процессора, и при этом данные расположены по выровненным адресам, тогда, возможно, синхронизация не обязательна.. по крайней мере на x86. но тогда не обязательно синхронизировать и доступ на запись по-моему, лучше защищаться в любом случае, потому что все зависит от особенности реализации одновременного доступа, а эта реализация везде своя
Nouzui Нет, конечно, — синхронизироваться приложениям тоже ведь надо. Не совсем так. Вообще, синхронизация нужна для исключения противоположной ситуации: рассинхронизации. Выше говорили почти правильно, только нужно думать не о байтах и двордах, а о некоторых законченных сущностях: для переменной размером в 1 байт это байт, для дворда это дворд, а для структуры — это вся структура: нельзя допускать, чтобы структура была обновлена только частично! (если это не сделано намеренно) Если данные не обновляются, то для простого чтения синхронизировать ничего не нужно; если же один или более потоков пишут в данные, то здесь уже нужна синхронизация, как для чтения, так и для записи: префикс lock для данных, размер которых не превышает 4 байта (в общем случае), критические секции, мьютексы, семафоры и т.п. — для остальных случаев. halyavin Для ассемблера Для ЯВУ нужно явно указывать, что переменная может быть изменена из других потоков (ключевое слово volatile для С/С++). Span (Инвариант.) Здесь имелось ввиду то, о чём я сказал выше: чтобы сущность данных (экземпляр структуры, класса) оставалась логически целостной до и после записи в неё.