Аналог FpNanoSleep для win32
Модератор: Модераторы
Аналог FpNanoSleep для win32
Есть ли для виндовса процедура типа sleep которая умеет останавливать поток на интервалы около 0.2 миллисекунды?
В обычной видне цикл переключения потоков составляет около 10 мс (в зависимости от производительности проца и числа ядер).
Фактическое время на команду sleep(1) как раз и будет 10, а не 1 мс. Этим обеспечивается общая производительность системы, т.к. переключение потоков отнимает много ресурсов проца.
Возможно, что на самых быстрых компах с малым числом запущенных задач время sleep(1) и приближается к 1 мс, я это не проверял, т.к. этой темой занимался несколько лет назад.
В свое время этой темой занимался плотно. Пришлось использовать системы реального времени под винду: RTX (http://citforum.ru/operating_systems/rtx/index.shtml). Тогда все эти доли миллисекунд прекрасно выдерживались. Только писать приходилось на С, т.к. API этого RTX под С.
Фактическое время на команду sleep(1) как раз и будет 10, а не 1 мс. Этим обеспечивается общая производительность системы, т.к. переключение потоков отнимает много ресурсов проца.
Возможно, что на самых быстрых компах с малым числом запущенных задач время sleep(1) и приближается к 1 мс, я это не проверял, т.к. этой темой занимался несколько лет назад.
В свое время этой темой занимался плотно. Пришлось использовать системы реального времени под винду: RTX (http://citforum.ru/operating_systems/rtx/index.shtml). Тогда все эти доли миллисекунд прекрасно выдерживались. Только писать приходилось на С, т.к. API этого RTX под С.
Мне не переключать потоки надо а подождать пока освободится занятый другим потоком ресурс, а если он занят слишком долго, то забить на обращение к нему до следующего витка главного цикла потока. Шанс на то что это случится невелик, большая точность ненужна. Для линукса посмотрел проседуру sleep и немного её изменил, в винде изменять нечего - используется готовая процедура из внешней библиотеки работающая с миллисекундами. В коде для винды обошёлся округлением наносекунд до миллисекунд - как-нибудь работать должно, если в линуксе ПО будет работать лучше, значит так сложились звёзды 
на мой взгляд, в вашем случае было бы логичнее использовать механизмы синхронизации потоков/процессов.
но если время процессора отдавать не хотите, то смотрите на
GetTickCount (точность ~ 1 ms) и на пару QueryPerformanceCounter, QueryPerformanceFrequency (точность зависит от камня).
Однако придется крутить цикл и выполнять ПУСТОЙ оператор (загрузка камня при этом ~ 100% одного ядра).
если ваш центральный камень однопросессорный, то ничего примечательного из этого не выйдет.
но если время процессора отдавать не хотите, то смотрите на
GetTickCount (точность ~ 1 ms) и на пару QueryPerformanceCounter, QueryPerformanceFrequency (точность зависит от камня).
Однако придется крутить цикл и выполнять ПУСТОЙ оператор (загрузка камня при этом ~ 100% одного ядра).
если ваш центральный камень однопросессорный, то ничего примечательного из этого не выйдет.
У меня 2 ядра, но писать надо так чтобы на большем количестве работало лучше а не хуже. Синхронизировать потоки не нужно, идея в том чтобы они работали автономно и принимали решение по мере поступления новых данных, причём порядок выполнения однотипных потоков менялся в зависимости от работы которую они выполняют и фич ОС. В линуксе всё вертится, мощности хватает, под вайном квест с компиляцией только начал проходить. Отдельное БЕ разработчикам винды за малый размер команды в cmd.exe, но вроде вписаться можно, в крайнем случае выручат симлинки с короткими путями.
Вначале Вы сказали, что нужны
Если Вас устраивают миллисекунды, то и обычный sleep будет работать, важно знать, что параметр у sleep указывает, что задержка будет не меньше, чем указана, но может быть больше.
Далее Вы говорите
Встречный вопрос, что за ресурс, и как Вы определяете, что он занят? Это темой я тоже в свое время плотно занимался, и получается, что без объектов синхронизации (функции ядра ОС) этого не достичь в принципе. А так как функции синхронизаии все равно использовать, то эти же функции позволяют выжидать, см. WaitForSingleObject, который возволит и синхронизировать и заменяет sleep. Другое дело, что ядро ОС по определению не кроссплатформенно, соответственно, раз Вы делаете кроссплатформенное ПО, то вынуждены использовать некие бибиотеки, адаптированные под разные ядра разных ОС.
Мне в свое время пришлось изучать всю эту кухню синхронизации, чтобы организовать по настоящему эффекетивное взаимодействие потоков и процессов. И в каждоый ОС это приходится изучать заново, есть кое-что общее, а есть уникальные нюансы. А нюасны как известно очень важны.
, но для винды - это только за счет расширения реального времени.Сквозняк писал(а):интервалы около 0.2 миллисекунды
Если Вас устраивают миллисекунды, то и обычный sleep будет работать, важно знать, что параметр у sleep указывает, что задержка будет не меньше, чем указана, но может быть больше.
Далее Вы говорите
.Сквозняк писал(а):подождать пока освободится занятый другим потоком ресурс
Встречный вопрос, что за ресурс, и как Вы определяете, что он занят? Это темой я тоже в свое время плотно занимался, и получается, что без объектов синхронизации (функции ядра ОС) этого не достичь в принципе. А так как функции синхронизаии все равно использовать, то эти же функции позволяют выжидать, см. WaitForSingleObject, который возволит и синхронизировать и заменяет sleep. Другое дело, что ядро ОС по определению не кроссплатформенно, соответственно, раз Вы делаете кроссплатформенное ПО, то вынуждены использовать некие бибиотеки, адаптированные под разные ядра разных ОС.
Мне в свое время пришлось изучать всю эту кухню синхронизации, чтобы организовать по настоящему эффекетивное взаимодействие потоков и процессов. И в каждоый ОС это приходится изучать заново, есть кое-что общее, а есть уникальные нюансы. А нюасны как известно очень важны.
>но для винды - это только за счет расширения реального времени.
Пусть её пользователи немного пострадают, если MS так решил, то это судьба. Тем более что разница не должна быть очень заметна.
>Встречный вопрос, что за ресурс, и как Вы определяете, что он занят?
Гоняются данные от потока к потоку. Обычно один поток пишет в переменную, остальные её только читают или один поток пишет, другой читает и стирает. Передаётся сложный составной тип состоящий из обычных глобальных переменных или массив состояцих их переменных такого типа. Писать можно только в свободную переменную - один из её элементов за это отвечающий должен быть = 0. Имеется другая переменная типа byte, если она = 0, то массив данных использовать можно, если = 1 то нельзя. Перед записью процедура пишет в эту переменную единицу, после записи ноль. Классы применяются только для организации потоков, всё остальное процедурщина диалекта {$MODE FPC} Ещё есть гуёвина написанная на лазарусе, вместо неё при компиляции можно использовать модуль заглушку. К сожалению полностью вырубить гуёвину во время работы программы нельзя, приходится её глушить и раньше она иногда перетягивала на себя фокус мышки и клавы, но если некоторое время вызывать application.processmessages; то этого не происходит.
>раз Вы делаете кроссплатформенное ПО, то вынуждены использовать некие бибиотеки, адаптированные под разные ядра разных ОС.
Ну и хорошо если под неподдерживаемые ОС программа так просто не налезет, лично мне хватает linux x86_64, linux x86, win32. win64 под вопросом и пока ненужен. Если программист сделает сразу всё, для всех и для всего, то он сам себе враг.
Пусть её пользователи немного пострадают, если MS так решил, то это судьба. Тем более что разница не должна быть очень заметна.
>Встречный вопрос, что за ресурс, и как Вы определяете, что он занят?
Гоняются данные от потока к потоку. Обычно один поток пишет в переменную, остальные её только читают или один поток пишет, другой читает и стирает. Передаётся сложный составной тип состоящий из обычных глобальных переменных или массив состояцих их переменных такого типа. Писать можно только в свободную переменную - один из её элементов за это отвечающий должен быть = 0. Имеется другая переменная типа byte, если она = 0, то массив данных использовать можно, если = 1 то нельзя. Перед записью процедура пишет в эту переменную единицу, после записи ноль. Классы применяются только для организации потоков, всё остальное процедурщина диалекта {$MODE FPC} Ещё есть гуёвина написанная на лазарусе, вместо неё при компиляции можно использовать модуль заглушку. К сожалению полностью вырубить гуёвину во время работы программы нельзя, приходится её глушить и раньше она иногда перетягивала на себя фокус мышки и клавы, но если некоторое время вызывать application.processmessages; то этого не происходит.
>раз Вы делаете кроссплатформенное ПО, то вынуждены использовать некие бибиотеки, адаптированные под разные ядра разных ОС.
Ну и хорошо если под неподдерживаемые ОС программа так просто не налезет, лично мне хватает linux x86_64, linux x86, win32. win64 под вопросом и пока ненужен. Если программист сделает сразу всё, для всех и для всего, то он сам себе враг.
Сквозняк писал(а):Писать можно только в свободную переменную - один из её элементов за это отвечающий должен быть = 0. Имеется другая переменная типа byte, если она = 0, то массив данных использовать можно, если = 1 то нельзя. Перед записью процедура пишет в эту переменную единицу, после записи ноль.
Если у Вас пишет только один поток, и только он меняет специальные переменные, а все остальные только читают и не меняют эти специальные переменные, то синхронизация без атомарных операций или без объектов синхронизации возможна. Но если уже два потока могут писать, или один пишет, а другой сбрасывают, то возможны коллизии, т.к. любое сравнение с переменное по умолчанию это не атомарная операция, т.е. if Flag=0 then не гарантирует, что в теле If Flag реально равен 0.
А для синхронизации не потоков а только конкретных массивов глобальных переменных ничего не придумано?
Сквозняк писал(а):А для синхронизации не потоков а только конкретных массивов глобальных переменных ничего не придумано?
Атомарные операции. http://efrazrabotka.ru/category/mnogozadachnost/
Unix. Взаимодействие процессов
Под Win должны быть Пайпы СпинБлокировки и Мьютексы. на счет очередей не знаю.. они в линухе меня не устраивают...
В вашем случае думаю мьютекс самое то.
PS. Книжка дает базу, ну а винда, Linux, BSD, это уже тонкости... (гугл в помощь).
Под Win должны быть Пайпы СпинБлокировки и Мьютексы. на счет очередей не знаю.. они в линухе меня не устраивают...
В вашем случае думаю мьютекс самое то.
PS. Книжка дает базу, ну а винда, Linux, BSD, это уже тонкости... (гугл в помощь).
Еще интересный материал http://wm-help.net/books-online/book/59464/59464-27.html. Я сам именно по этой книге изучал эту тему.
