Zobacz tutaj
Istnieją dwa sygnały, które mogą zawiesić wykonanie procesu. Jeden jest „pełen wdzięku”, a drugi „silny”.
Ten „pełen wdzięku” jest SIGTSTP
, a jego celem jest „ładnie” poprosić proces, jeśli ma na to ochotę, o zawieszenie wykonania do czasu otrzymania SIGCONT
. W takim przypadku SIGTSTP
proces może zignorować SIGTSTP i kontynuować wykonywanie mimo to, więc wymaga to współpracy programu, który jest zaprojektowany do obsługi SIGTSTP.
„Mocny” jest SIGSTOP
, a jego celem jest zawieszenie wszystkich wątków przestrzeni użytkownika powiązanych z tym procesem. Zignorowanie procesu jest tak samo niemożliwe, jak zignorowanie SIGSTOP
go SIGKILL
(ten ostatni silnie zabija proces).
Aby wysłać dowolny sygnał, w tym każdy z wymienionymi tutaj, można korzystać z programów takich jak kill
, killall
lub pkill
; lub użyj wywołania systemowego kill(2)
. Zobacz strony systemu operacyjnego, aby uzyskać szczegółowe informacje na temat platformy / architektury / wersji oraz erratę dotyczące któregokolwiek z powyższych. Zauważ, że słowo „zabij” we wszystkich tych poleceniach i wywołanie systemowe jest złym błędem. Te polecenia nie są przeznaczone wyłącznie do przerywania procesów. Mogą to zrobić, wysyłając określone sygnały; ale sygnały mogą być również wykorzystane do funkcji innych niż zakończenie procesu. Na przykład SIGSTOP
tylko zawiesza proces i jest to tylko jeden z kilku sygnałów, które można wysłać w ten sposób.
Aby dodać warunek automatycznego wznawiania procesu po upływie określonego czasu, należy użyć pewnego rodzaju procesu monitorowania, który pozostaje uruchomiony i ustawia licznik czasu w celu wznowienia procesu monitorowania, który następnie z kolei wywołuje kill(2)
ponownie i wysyła SIGCONT
sygnał do zatrzymanego procesu, aby zażądać od jądra wznowienia wykonywania. Zauważ, że Linux ma kilka mechanizmów synchronizacji z różnymi stopniami dokładności i precyzji; ponadto, jeśli twój system jest bardzo zajęty, proces monitorowania może się nie obudzić, dopóki nie upłynie czas jego licznika, a zatem budzenie może się opóźnić.
Jeśli zależy na bardzo dokładną precyzją zawieszenia i wznowienia zawieszonego procesu, może być konieczne, aby uruchomić program z uprawnieniami do monitorowania w czasie rzeczywistym (patrz ten podręcznik na sched_setscheduler(2)
informacje na temat dokonywania procesu w czasie rzeczywistym). Możesz także użyć Timerów o wysokiej rozdzielczości, funkcji jądra Linuksa (która jest dostępna tylko wtedy, gdy twój sprzęt zapewnia ich obsługę), w połączeniu z planowaniem w czasie rzeczywistym, aby uzyskać bardzo dokładną, poniżej milisekundową precyzję taktowania, a następnie Obudź się i wyślij sygnał, aby bardzo szybko wznowić monitorowany proces.
Nie wskazałeś, z których technologii chcesz skorzystać, aby to wdrożyć. Co najmniej będziesz potrzebował przynajmniej bashowych skryptów, chociaż nie będziesz w stanie uzyskać bardzo precyzyjnego timingu w ten sposób. Oto „skrypt” bashowy (niesprawdzony, więc bądź ostrożny), który jest tylko dowodem koncepcji twojego zapytania. Jeśli potrzebujesz dokładnego pomiaru czasu, będziesz musiał napisać program, prawdopodobnie w C / C ++ lub innym języku ojczystym, i używać harmonogramów w czasie rzeczywistym i hrtimerów.
#!/bin/bash
#This is the process you want to suspend.
screen -mdS child bash -c "cat /dev/urandom | base64"
#This is the process ID of the child process
THEPID=$(screen -list | grep child | cut -f1 -d'.' | sed 's/\W//g')
#Send SIGSTOP to the child process.
kill -SIGSTOP ${THEPID}
#Now it is suspended. This process will sleep for 10 seconds asynchronously, then resume the process.
screen -mdS monitor bash -c "sleep 10; kill -SIGCONT ${THEPID}"
Zauważ, że skrypt zakończy się, a skrypt kontrolny zakończy się, ale ze względu na screen
kontrolowanie procesu monitorowania, będzie on nadal działał w tle przez 10 sekund (na podstawie przekazanego argumentu sleep
), a następnie obudzi się i będzie kontynuował proces potomny. Ale to potrwa długo po zakończeniu skryptu sterującego. Jeśli chcesz synchronicznie czekać na upływ czasu, po prostu pomiń drugie wywołanie screen
i zakoduj uśpienie i zabij do skryptu sterującego.
Możesz sprawdzić, czy proces faktycznie zawiesił się, uruchamiając
screen -rS child
po uruchomieniu tego skryptu. Nic nie zobaczysz na konsoli. Następnie, po upływie czasu (10 sekund), ekran zostanie zalany danymi base64 (losowe znaki od 0-9 i AF). Naciśnij Ctrl + C, aby wyjść.