| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Точный Sleep() |
| Автор: NextAlex 20.3.2006, 18:57 | ||||
| Привет всем! Возникла проблема, с которой никак не могу справиться. Есть программа, работающая с железякой через COM-порт. В бесконечном цикле записывается несколько управляющих пакетов, последний из которых - запрос состояния после чего считывается ответ. Всё бы хорошо, но нужно чтобы общение проходило на максимально возможной скорости, в смысле цикл запись-чтение повторялся с максимально возможной частотой. Но при записи в порт без временного разрыва между пакетами происходит толи переполнение буфера записи, толи железяка не успевает принимать передаваемые пакеты и появляются потери данных. Помахавшись я понял что после записи пакета необходимо делать паузу около 5 мс и тогда полный порядок, но стандартный Sleep() делает паузу с точностью в 10 - 15 мс, а написанный мной держит точно, но слишком уж сильно загружает процессор, что не удивительно Посоветуйте что можно сделать. вот мой sleep:
ну и функция записи:
|
| Автор: _hunter 20.3.2006, 19:07 |
| понизь приоритет потока. + что ты хотел? -- и скорость держать и ресурсы не занимать? |
| Автор: NextAlex 20.3.2006, 19:20 |
| я понимаю что ты эксперт и все понты Ресурсы в моем случае занимает как раз sleep, потому что строка Sleep(0) выполняется порядка 4-5 микросекунд и запрос времени около 2-3 микросекунд, соответственно на каждую милисекунду слипа проходит порядка 150 циклов конкретно загрузки процессора ... |
| Автор: _hunter 20.3.2006, 19:46 |
| смотрел. ни слова о приоритете потока там нет. + непонятны твои претензии. пусть один sleel уходит 8мкс. тогда на 1000 sleel-ов уйдет 8сек (нигде не ошибся? ) а если ты понизиш приоритет -- за это же время управление на твой поток передадут 500 раз ( при наличии других потоков ) |
| Автор: maxim1000 20.3.2006, 20:12 |
| в подобных случаях, ИМХО, самый эффективный путь использования скорости канала - подтверждение приема т.е. когда железяка готова принимать, она посылает сигнал, когда не готова - другой в COM-порте для этого есть специальных линии: RTS, CTS 1 - можно передавать, 0 - нельзя (или наоборот, не помню) ну или можно в сам поток данных вставлять пакеты такого назначения если железяка своя - реализовать это проблем не составит если чужая - стоит посмотреть, нет ли у нее какого-нибудь способа сообщать готовность... |
| Автор: NextAlex 21.3.2006, 00:10 |
| _hunter, а я и не говорил что там есть что-то о приоритете ... просто этот способ не подходит, поскольку кроме общения с железякой программа параллельно выполняет еще насколько задач и если приоритет потока чтения/записи не будет хотя бы NORMAL_PRIORITY, то задержки начинают появляться в самый неподходящий момент и становится еще хуже. А Sleep(0) не передает управление другим потокам, поэтому ресурсов такая схема загребает по-максимуму. maxim1000, насчет RTS и CTS я знаю, но железяка не поддерживает эти сигналы и переделать возможности пока нет. Посему потребность в точном слипе остается. Может кто-то знает как вообще работает Sleep ? Или может кто встречал исходники чего-то подобного ? И еще может кто знает как перехватить прерывание мыши ? |
| Автор: bilbobagginz 21.3.2006, 00:39 |
| переходи на *nix и юзай usleep() ( микрослип - микросекунды ) или вообще rtc ( real time clock ) пока. |
| Автор: NextAlex 21.3.2006, 00:43 |
| bilbobagginz, к чему и стремлюсь, тока вот под виндами нужно сначала доделать |
| Автор: NextAlex 21.3.2006, 15:28 | ||
_hunter, мне это начинает надоедать
Тебе прислать программку, которая будет спать по этому методу секунд 30, чтобы ты мог ощутить всю полноту тормозов я понимаю что ты умный и все такое и я на самом деле так думаю после того как почитал парочку твоих постов, но вот упрямый ты как стадо баранов. Будь человеком - оставь мои потоки и алгоритм в покое Скажи что-нить дельное насчет слипа... |
| Автор: SergeCpp 21.3.2006, 15:34 |
| MSDN Sleep The Sleep function suspends the execution of the current thread for at least the specified interval. To enter an alertable wait state, use the SleepEx function. VOID Sleep( DWORD dwMilliseconds ); Parameters dwMilliseconds [in] Minimum time interval for which execution is to be suspended, in milliseconds. A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution. |
| Автор: Earnest 21.3.2006, 15:44 |
| Веди себя прилично, будь другом - это ведь ты помощи просишь. Тебе русским языком говорят - не получится под Win сделать более точный Sleep (разве что таким способом, как ты сделал в начале, с пожиранием процессорного времени). То, что стандартный Sleep работает с довольно большой дискретностью - завязано на передачу управления между потоками, а не потому, что дяди из Редмонда туда тебе назло задержки встроили. Так что ищи другой выход - пересматривай свои алгоритмы, как уже было сказано. |
| Автор: SergeCpp 21.3.2006, 15:52 |
| MSDN The SleepEx function suspends the current thread until one of the following occurs: An I/O completion callback function is called Не поможет? |
| Автор: NextAlex 21.3.2006, 16:20 |
| Earnest, К сожалению не могу никак вспомнить твое имя, посему буду обращаться как получится ... Насчет того что я обратился за помощью я в курсе, но меня честно говоря раздражает когда знающий человек начинает ну если ни нести пургу, то во всяком случае не может толком пояснить свою мысль. Я старался не сказать _hunter ничего сильно обидного, хотя в первый момент желание было. Почему слип спит неодинаковое время я тоже знаю ... а вот насчет дискретности (если ты конечно это слово хотела сказать) могу с тобой довольно активно поспорить, есть желание - пиши в аську Если за невозможности создать более точный слип под виндами выскажется еще кто-то, то я скорее всего соглашусь с этим, а пока вопрос остается открытым. Алгоритмы пересмотрены были уже не один раз. PS. Дабы избежать лишних непоняток прошу мнение излагать более внятно чем _охотник. PPS. Я не хочу никого обидеть, просто временами у меня стиль общения не очень приятный и подзадолбался я в последние дни. Посему у всех на кого мои слова произвели плохое впечатление и на кого они еще произведут таковое прошу прощения. |
| Автор: _hunter 21.3.2006, 16:52 |
| значит ставь задачу заново. потому как из первого твоего поста следует что проблемой является чрезмерная загрузка процессора, а из последнего -- низкая точность решения... |
| Автор: NextAlex 21.3.2006, 17:20 |
| _hunter, пытался добавить тебе плюс в репутацию за то что не обиделся, но за неимением необходимого количества постов не получилось, посему добавь себе сам от моего имени По большому счету изменение алгоритма или приоритета потока я выходом не считаю. Уточненние задачи: нужен аналог стандартной функции Sleep(), который будет отличаться более точным временем сна (хотя бы ±2мс) и не будет слишком сильно грузить процессор. Кстати, признаю что изначально вопрос был поставлен не совсем точно ... SergeCpp, по-моему она отличается только тем что может быть прервана, но сейчас попробую. |
| Автор: Romikgy 21.3.2006, 17:23 |
| плохо раз знаешь то чего спрашиваешь? Имхо если железяка ваша, в ней ковырятся нужно |
| Автор: NextAlex 21.3.2006, 17:37 |
| я бы с удовольствием |
| Автор: Romikgy 21.3.2006, 17:47 |
| 1. вопрос, почему посылаются только по 5 байтов? имхо посылатся должен весь пакет, а железяка, должна переваривать что кому, если она многофункциональная, и 2. винда никогда не гарантировала, соблюдения каких либо интервалов, она многопотоковая (имхо могу с названием путать гуру поправят) и для каждого процесса выделяется квант процессорного времени (думаю что это ты и так знаешь надо юзать события, или привязыватся к порту/железу , мож ксати ждущий таймер те подойдет, но тоже не уверен, что у него точность выше |
| Автор: NextAlex 21.3.2006, 18:06 | ||
| это и есть весь пакет
етсть много неразумных вещей, которые почему-то работают |
| Автор: Earnest 21.3.2006, 18:10 | ||
А я уверена - точно такая же (из той же бочки наливают). Сама не так давно сильно обломалась. Т.е. не спасет. |
| Автор: Romikgy 22.3.2006, 09:51 |
| имхо не совсем Пусть будет так |