Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« : 07-06-2011 06:31 » |
|
Что-то я , видимо, не до конца понимаю, как он работает. запускаю так timeBeginPeriod(1); //1 мс - период моего таймера ::CreateTimerQueueTimer(&m_h,0,pf,pContext,1,1,WT_EXECUTEDEFAULT|WT_EXECUTEINTIMERTHREAD); то есть запуск с самого начала, плюс запускается отдельный поток где-то в системе (это видно в диспетчере задач, если запустить таймер, становится на 1 поток у процесса больше). У меня раз по этому таймеру раз в 1 мс вызывается процедура , и на шустром компе я с удивлением обнаружил, что произошло переполнение стека - ещё не произошёл выход из процедуры, как уже был выполнен новый вход. И аж 33 раза, как показала трассировка! Не могу понять, как такой в одном потоке может произойти. Рекурсии нет точно
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #1 : 07-06-2011 06:51 » |
|
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 07-06-2011 06:52 » |
|
выяснил опытным путём, что повторный вызов происходит, если в процедуре вызываю FTDI функцию FT_CreateDeviceInfoList (возможно, не только она это делает, а другие FTDI-функции тоже) >>У тебя какая операционка? XP+SP3 Добавлено через 1 минуту и 57 секунд:установка критической секции в начале всей функции эффекта не даёт - значит, поток один Добавлено через 41 минуту и 24 секунды:обернул флагом bIsHere - вроде перестало фигнёй страдать void MyFunc() { static bool bIsHere=false; static int counter=0;
if(bIsHere) { TRACE("bIsHere\r\n"); return; }
bIsHere=true;
counter++; TRACE("counter=%d\r\n",counter);
_____MyFunc();
counter--; TRACE("counter=%d\r\n",counter);
bIsHere=false; }
void _____MyFunc() { ... }
трейс: m_mmtimer.start counter=1 bIsHere bIsHere bIsHere bIsHere counter=0 counter=1 bIsHere bIsHere bIsHere counter=0 counter=1 bIsHere bIsHere counter=0 counter=1 bIsHere bIsHere bIsHere<...> И всё-таки, может надо как-то по другому? Или никак
|
|
« Последнее редактирование: 07-06-2011 07:36 от Алексей1153 »
|
Записан
|
|
|
|
baldr
|
|
« Ответ #3 : 07-06-2011 07:39 » |
|
Алексей1153++, а сколько времени выполняется _____MyFunc() ?
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 07-06-2011 07:49 » |
|
baldr, бывает по разному. Там проверяется и открывается, если ещё не открыт, USB порт, производится опознание прибора на том конце - вот это долго делается (1...5 секунд)
а если порт уже открыт, всё быстро делается
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #5 : 07-06-2011 08:05 » |
|
Алексей1153++, а как насчет этого? Applications should not call any system-defined functions from inside a callback function, except for PostMessage, timeGetSystemTime, timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg, midiOutLongMsg, and OutputDebugString.
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 07-06-2011 08:13 » |
|
baldr, а мне иначе нельзя... Этот таймер только для того и был запользован, чтобы точно с этим интервалом вычитывать данные, иначе у FTDI-драйвера крышу сносит (поток данных большой). Ладно, время и тестирование покажет
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #7 : 07-06-2011 08:45 » |
|
Попробуй вот эту обертку. Я в свое время чем-то похожим пользовался. http://www.codeproject.com/KB/audio-video/mult_media_timer.aspxЯ, помнится, даже на форме рисовал внутри обработчика
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 07-06-2011 09:03 » |
|
ок, попробую, если проблема снова появится.
А в чём там особенность? Я не понял с ходу
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #9 : 07-06-2011 09:09 » |
|
Да просто обертка над таймером - удобнее использовать. Уже не помню деталей,но,по-моему у меня не было таких проблем с реентрабельностью. У меня опрашивалось внешнее устройство, рисовалось и еще хрен знает что делалось в этом коллбэке - и ничего
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 07-06-2011 09:12 » |
|
baldr, так я ж ничего не говорю, видимо дело именно в том, что я вызываю АПИ FTDI , а что у них там унутри - Аллах ведает )
|
|
|
Записан
|
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #11 : 07-06-2011 12:53 » |
|
Как вариант - пусть таймер устанавливает событие, вместо вызова call back, а Ваш поток пусть висит на этом событии, как оно произошло - вычитывает из устройства и делает всё, что необходимо.
|
|
« Последнее редактирование: 07-06-2011 12:54 от darkelf »
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #12 : 07-06-2011 13:18 » |
|
darkelf, +1 Я бы тоже так делал...
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #13 : 07-06-2011 13:21 » |
|
Мне кажется это не дает требуемой точности.
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #14 : 07-06-2011 14:10 » |
|
Мне кажется это не дает требуемой точности.
Зато будет правильно работать, и при достаточном приоритете потока, точности может и хватить.
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #15 : 07-06-2011 14:23 » |
|
Ну при таком подходе нет смысла использовать мультимедийный таймер - хватит и стандартного... Тем более, что события возможно им и отрабатываются.
Мультимедийный таймер нужен для того, чтобы считывать данные с внешних устройств с достаточной синхронностью. Если делать это по событию - будут задержки из-за обработки очереди событий.
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
darkelf
Молодой специалист
Offline
|
|
« Ответ #16 : 07-06-2011 14:41 » |
|
Синхронность как-раз и будет достигаться за счёт приоритета потока, т.к. при достаточно высоком его уровне, он, при наличии ожидающего события от таймера, будет немедленно запускаться.
|
|
|
Записан
|
|
|
|
baldr
|
|
« Ответ #17 : 07-06-2011 14:56 » |
|
darkelf, частота стандартного таймера - величина не постоянная. Она может "плавать" в довольно широких пределах. Он не обеспечит заданной точности - только потому что не предназначен для таких задач. К сожалению, не приведу сейчас документальных доказательств. Идея с событиями, безусловно, применима здесь - то есть по мультимедийному таймеру из устройства читаются данные и заносятся в буфер, а потом взводится флаг события. Другой поток уже по событию или по стандартному таймеру может читать из этого буфера и рисовать графику, например.
|
|
|
Записан
|
Приличный компьютер всегда будет стоить дороже 1000 долларов, потому что 500 долларов - это не вполне прилично
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #18 : 07-06-2011 16:53 » |
|
darkelf, Kivals, нет нет, никаких флагов срабатывания или WM_TIMER - это всё уже пройдено. Нужно как можно быстрое вычитывание данных из драйвера, иначе он зависает. Именно поэтому ПРИШЛОСЬ применить ММ таймер. А иначе стал бы я с этим гемором биццо
|
|
|
Записан
|
|
|
|
|