Jestem programistą wbudowanym, który próbuje symulować planowanie zapobiegawcze w czasie rzeczywistym w środowisku Win32 przy użyciu Visual Studio 2010 i MingW (jako dwóch oddzielnych środowisk kompilacji). Jestem bardzo zielony w środowisku planowania Win32 i uderzyłem w mur z tego, co próbuję zrobić. Nie próbuję osiągnąć zachowania w czasie rzeczywistym - wystarczy, aby symulowane zadania były uruchamiane w tej samej kolejności i kolejności, jak w rzeczywistym sprzęcie docelowym.Planowanie wątków systemu Win32 do zdefiniowanej sekwencji na podstawie priorytetu
Symulowany program planujący w czasie rzeczywistym ma prosty cel - zawsze wykonywać zadanie o najwyższym priorytecie (wątek), które można uruchomić. Gdy tylko zadanie stanie się możliwe, musi uprzedzić aktualnie uruchomione zadanie, jeśli ma wyższy priorytet niż aktualnie uruchomione zadanie. Zadanie może zostać uruchomione ze względu na zdarzenie zewnętrzne, na które czekał, lub upłynął limit czasu/czasu blokowania/czasu uśpienia - z przerwą zaznaczającą podstawę czasu.
Oprócz tego poboru zachowania zadanie może dawać albo ochotnika zrezygnować z przedział czasu, ponieważ to realizuje się funkcję uśpienia lub czekać typu.
Symuluję to, tworząc wątek Win32 o niskim priorytecie dla każdego zadania tworzonego przez symulowaną symulację czasu rzeczywistego (wątek skutecznie przełącza konteksty, które planista wykonywałby na rzeczywistym docelowym obiekcie osadzonym), średni priorytet Wątek Win32 jako pseudo przerywnik obsługi (obsługuje symulowane przerwania i żądania yield, które są sygnalizowane do niego przy użyciu obiektu zdarzenia Win32), a wątek Win32 o wyższym priorytecie symuluje urządzenie peryferyjne, które generuje przerwania.
Gdy obsługa pseudo przerwań ustali, że powinien wystąpić przełącznik zadań, zawiesza bieżący wątek za pomocą metody SuspendThread() i wznawia wątek, który wykonuje nowo wybrane zadanie za pomocą funkcji ResumeThread(). Spośród wielu zadań i skojarzonych z nimi wątków Win32, które mogą być tworzone, tylko jeden wątek, który zarządza zadaniem, nigdy nie będzie znajdował się w stanie zawieszenia.
Ważne jest, aby zawieszona nić zawiesiła natychmiast wywołanie metody SuspendThread() i aby wątek obsługi pseudo przerwań został wykonany, gdy tylko zostanie wydane powiadomienie, że przerwanie jest w toku - ale to nie jest zachowanie widzę.
Jako przykładowy problem, nad którym już pracowałem: Gdy zadanie/wątek daje zdarzenie wydajności jest zablokowane w zmiennej i wątek obsługi przerwań jest sygnalizowany, ponieważ istnieje pseudo przerwanie (wydajność), które wymaga przetwarzanie. Teraz w systemie czasu rzeczywistego, jak jestem przyzwyczajony do programowania, oczekiwałbym natychmiastowego uruchomienia wątku obsługi przerwania, który jest sygnalizowany, ponieważ ma wyższy priorytet niż wątek, który go sygnalizuje. To, co widzę w środowisku Win32, to wątek, który sygnalizuje wątek o wyższym priorytecie przez jakiś czas, zanim zostanie zawieszony - ponieważ zajmuje trochę czasu, zanim wątek o wyższym priorytecie zacznie się uruchamiać lub ponieważ trwa to dłużej zadanie, aby faktycznie przestać działać - nie jestem pewien, który. W każdym razie może to być łatwo poprawne poprzez utworzenie blokowania wątku Win32 na semaforze po sygnalizowaniu wątku obsługi przerwań Win32, i użycie wątku Win32 w celu przerywania wątku odblokowuje wątek po zakończeniu jego funkcji (uzgadnianie). Efektywnie za pomocą synchronizacji wątku wymuszam schemat harmonogramu na to, czego potrzebuję. Używam do tego celu SignalObjectAndWait().
Stosując tę technikę symulacji działa perfekcyjnie, gdy harmonogram czasu rzeczywistego są symulowane działa w trybie kooperacji - ale nie (tak jak jest to konieczne) w trybie poboru.
Problem z przełączaniem zadań prewencyjnych jest taki sam, zadanie to jest kontynuowane przez pewien czas po tym, jak kazano mu zawiesić, zanim faktycznie przestanie działać, więc nie można zagwarantować, że system pozostanie w stanie spójnym, gdy wątek, który uruchamia zadanie, zawiesza się. W przypadku prewencyjnym jednak, ponieważ zadanie nie wie, kiedy ma się wydarzyć, nie można użyć tej samej techniki używania semafora, aby zapobiec dalszym błędom Win32, dopóki nie zostanie on ponownie wznowiony.
Ktoś zrobił tak daleko w tym poście - przepraszam za jego długość!
Moje pytania są więc:
Jak mogę zmusić Win32 (XP) harmonogram, aby rozpocząć i natychmiast zatrzymać zadania, że zawiesić i wznowić funkcje gwint nazywane są - lub - jak mogę zmusić wyższy priorytet Wątek Win32, aby rozpocząć wykonywanie od razu, że jest to w stanie wykonać (obiekt, na którym jest zablokowany, jest sygnalizowany). Skutecznie zmuszając system Win32 do zmiany harmonogramu uruchomionych procesów.
Czy istnieje sposób asynchronicznego zatrzymania zadania, aby czekać na zdarzenie, gdy nie znajduje się w ścieżce wykonywania sekwencji/wątków zadań/wątków.
Symulator działa dobrze w środowisku Linux, w którym sygnały POSIX są używane do skutecznego przerywania wątków - czy istnieje odpowiednik w Win32?
Dzięki każdemu, kto podjął czasu na przeczytanie tego długiego posta, a zwłaszcza z góry dzięki każdemu, który może pomieścić rękę „Real mechaników czasu” przez ten labirynt Win32.
Ale włókna nie będą działać jednocześnie na wielu rdzeniach. –
Dzięki za cynk.Będę jutro sprawdzał materiał referencyjny na temat włókien. – Richard
@Zan: wiele włókien może działać w jednym wątku i można uruchomić wiele wątków, po jednym dla każdego rdzenia. –