Chcę zaimplementować sposób zaplanowania zadania, które ma zostać wykonane w późniejszym czasie. Interfejs będzie podobny do JavaScriptu setTimeout(function, milliseconds)
.Zadania opóźnione w C++
W mojej aplikacji niektóre zasoby są własnością wątku. Aby uniknąć warunków wyścigowych, muszą być zawsze dostępne z tej samej nitki. Jeśli inne wątki chcą uzyskać dostęp do zasobu, muszą wysłać obiekt zadania do wątku zasobów.
więc dwa problemy muszę rozwiązać to:
- wysłanie zadania do wątku
- opóźnienia inwokacja
Pierwszy problem szybko rozwiązać używając kolejkę blokady wolne który ma wątek zasobów po stronie konsumującej. (Używam TBB's concurrent_bounded_queue.) Drugi problem nie jest jednak dla mnie tak oczywisty. Mogę wymyślić dwie strategie:
- Rozpocznij nowy wątek dla każdego zadania. Ten wątek przesłoni wymagane opóźnienie, a następnie wywoła zadanie do kolejki współbieżnej.
- Uruchomić tylko jeden wątek, który uruchamia pętlę, która iteruje zaplanowane zadania i wywołuje je, jeśli upłynął ich czas oczekiwania.
Eksperymentowałem z obydwoma podejściami i preferuję pierwsze, ponieważ jest proste i niezawodne, podczas gdy drugie jest bardziej podatne na subtelne błędy. Pierwsze podejście deleguje to do programu planującego wątki systemu operacyjnego.
Jednak pierwsze rozwiązanie tworzy wiele krótkotrwałych wątków, a ja zazwyczaj słyszę zalecenie ponownego użycia wątków.
Nie ma żadnej gwarancji w drugim podejściu do szybkiego przeprowadzenia egzekucji. Czasami przed wykonaniem drugiego zadania należy poczekać na zakończenie jednego zadania. Pierwsze podejście jest lepsze. –
Czy liczba zarodkowanych wątków naprawdę będzie tak duża? Jak kilka houndred tysięcy? Pamiętaj, że śpiące wątki pochłaniają prawie 0 czasu procesora. –
@BartekBanachewicz W mojej aplikacji nie będzie wielu jednocześnie zaplanowanych zadań. Zazwyczaj wykonują akcję co N milisekund. Robią to przez zmianę harmonogramu, zanim umrą. – StackedCrooked