Może to powinno być w Delphi (bo w Delphi piszę) ale problem jest raczej natury ogólno-Windowsowej, więc daję tutaj.
Otóż mam program komunikujacy się z otoczeniem przez port LPT (lub w przyszłości kartę I/O jakąś może). Istotny jest timing - zmiany na porcie muszą być wykrywane z dużą precyzją czasową. Tzn. program nie musi wiedziec o nich natychmiast (choć bez przesady z opóźnieniami), ale musi wiedzieć możliwe dokładnie kiedy zaszły.
Zorganizowałem sobie to tak. Jest główny program, wątek obsługi portu i struktura komunikacji będącą dwoma buforami FIFO z dostępem chronionym sekcją krytyczną. Jeden bufor (nazwijmy go A) służy do komunikacji z programu do wątku, drugi (B) do komunikacji z wątku do programu.
Wątek obsługi portu chodzi w niedużej pętli, permanentnie przegląda port, i zagląda do bufora A, z którego zdejmuje "komendy" - odczytaj port, obserwuj piny takie-a-takie i zgłaszaj zmiany, itp. Jak ma odczytać, to wpisuje wynik do bufora B, jak zobaczy zmianę na obserwowanych pinach do też wpisuje ja do bufora B. Powtarza też "komendy" z A wpisując je do B dla kontroli czasu. Wszystkie "komendy" w buforach A i B mają zapisany czas z QueryPerformanceCounter, więc mogę miec pojęcie ile co zajmuje.
No a główny program jak ma czas zagląda do bufora B i zdejmuje odpowiedzi z atku przegladającego i robi z nimi co trzeba, w tym pisze do pliku, oraz wysyła komendy do bufora A.
Problem mam z sensownym dopasowaniem obciążenia procesora przez wątek przegladający port. Dałem go z wysokim priorytetem (tpTimeCritical, próbowałem też tpHighest) żeby nic go nie wywałaszczyło kiedy powienien zadziałać. Ale oczywiście wtedy użycie procesora skacze do 100% (w tej chwili 50% bo mam procesor HT). Dałem w pętli SwitchToThread; (oddaj do innego wątku) żeby nie zawieszał systemu - nadal 100(50)%. I nie dziwne, bo zwykle żaden inny wątek nie czeka, więc nie ma komu oddac procesora. Tak samo jak się da SleepEx(0,True) - który zasadniczo też powoduje oddanie time slice przez wątek. SleepEx(1, True) niby rozwiązuje sprawę - ale przesadnie, bo wartość 1 jest DWORD w milisekundach. A ja wolałbym, żeby wątek chodził gęściej, powiedzmy co 10-50 mikrosekund.
Macie jakiś pomysł jak go zmusić żeby chodził tak często bez przeciążania procka?
A jeśli nie, to czy ustawienie ze SwitchToThread lub SleepEx(1,True); i procesor wypełniony na maksa czymś grozi? czym?
A może jakis pomysł na inną organizację programu? (choć wolałbym nie, bo rzecz jest już napisana ;) )