Linux'ta bir işlem geçici olarak dondurulabilir mi?


53

Belirli bir süre boyunca herhangi bir işlemi dondurmanın bir yolu olup olmadığını merak ediyordum.

Demek istediğim şudur: bir uygulamanın (muhtemelen kök olarak çalışan) bir başka çalışmakta olan işlemin (herhangi bir işlem, hem GUI hem de komut satırı) yürütülmesini duraklatması ve daha sonra devam etmesi mümkün mü? Başka bir deyişle, belirli işlemlerin linux zamanlayıcı tarafından belirli bir süre için planlanmasını istemiyorum.

Yanıtlar:


81

Buraya bak

Vardır , iki , bir işlemin yürütülmesi askıya olabilir sinyaller. Biri "zarif" ve biri "kuvvetli".

“Zarif” olanı SIGTSTPve amacı, süreci “hoş bir şekilde” istemesi, eğer böyle hissederse, ihaleyi a olana kadar askıya almaktır SIGCONT. Bu durumda SIGTSTP, süreç SIGTSTP'yi görmezden gelebilir ve yine de yürütülmeye devam edebilir, bu nedenle SIGTSTP'yi idare etmek için tasarlanmış bir programdan işbirliğini gerektirir.

"Zorlu" olanıdır SIGSTOPve amacı, bu işlemle ilişkili tüm kullanıcı alanı iş parçacıklarını askıya almaktır. Sürecin görmezden geldiği SIGSTOPgibi görmezden gelmesi de imkansızdır SIGKILL(ikincisi süreci zorla öldürür).

Aşağıdaki gibi programları kullanabilirsiniz Burada sözü olanlar herhangi dahil keyfi bir sinyal göndermek için kill, killallya da pkill; veya sistem çağrısını kullanın kill(2). Yukarıdakilerden herhangi biriyle ilgili olarak platform / mimari / versiyona bağlı ayrıntılar ve işletim sistemi için işletim sisteminizin man sayfalarına bakın. Tüm bu komutlarda ve sistemde "öldür" kelimesinin kötü bir yanlış isim olduğuna dikkat edin. Bu komutlar şunlardır değil tasarlanmış, münhasıran işlemleri sonlandırmak için. Bunu sinyallerden bazılarını göndererek yapabilirler ; ancak sinyaller, bir işlemi sonlandırmaktan başka işlevsellik için de kullanılabilir. Örneğin, SIGSTOPyalnızca süreci askıya alır ve bu şekilde gönderilebilecek birkaç sinyalden yalnızca biridir.

Otomatik bir süre geçtikten sonra sürecinin devamının bir koşulu eklemek için, çalışan kalır ve daha sonra sırayla çağırır izleme sürecini, uyanmak için bir zamanlayıcı ayarlar izleme sürecinin çeşit kullanmanız gerekecektir kill(2)tekrar SIGCONTçekirdeğin yürütmeyi sürdürmesini istemek için sinyali durdurulan işleme gönderir . Linux'un çeşitli doğruluk ve hassasiyet derecelerinde çeşitli zamanlama mekanizmalarına sahip olduğunu unutmayın; ayrıca, eğer sisteminiz çok yoğunsa, izleme işleminiz zamanlayıcısının süresi doluncaya kadar uyanamayabilir ve bu nedenle uyanma gecikebilir.

Askıya sürecin askıya alınması ve geri çok hassas hassas yapılması gerekir ise, gerçek zamanlı izinleri ile izleme programını çalıştırın (bkz gerekebilir bu manpage üzerinde sched_setscheduler(2)Prosesinizi gerçek zamanlı yapma konusunda bilgi almak için). Ayrıca, zamanlamada çok hassas, milisaniyenin altında bir hassasiyet elde etmek için Linux çekirdeğinin bir özelliği olan (yalnızca donanımınız onlara destek sağlarsa kullanılabilir) Yüksek Çözünürlüklü Zamanlayıcıları da kullanabilirsiniz. uyandırın ve izlenen süreci çok hızlı bir şekilde devam ettirmek için sinyal gönderin.

Bunu uygulamak için hangi teknolojileri kullanmak istediğinizi belirtmediniz. Çıplak bir şekilde, en azından çok iyi ayarlanmış zamanlamayı bu şekilde elde edemeseniz de en azından bash komut dosyası gerekir. İşte bir bash "script" (denenmemiş, lütfen dikkatli olun) bu sadece sorgunuzun konseptinin bir kanıtıdır. Kesin zamanlamaya ihtiyacınız varsa, muhtemelen C / C ++ veya başka bir ana dilde bir program yazmanız ve gerçek zamanlı zamanlama ve hrtimerler kullanmanız gerekir.

#!/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}"

Komutun sona ereceğini ve kontrol komut dosyasının sonlanacağını unutmayın; ancak screenizleme işleminin kontrol edilmesi nedeniyle , arka planda 10 saniye (devam eden argümana göre sleep) çalışmaya devam eder ve sonra uyanıp alt işleme devam eder. Ancak bu kontrol senaryosunun sona ermesinden çok sonra olacaktır. Eşzamanlı olarak zamanın geçmesini beklemek istiyorsan, ikinci aramayı atla ve uyumu screenzorla kodla ve kontrol komut dosyasına öldür.

Sürecin çalışarak askıya alındığını test edebilirsiniz.

screen -rS child

Bu betiği başlattıktan sonra. Konsolda hiçbir şey göremezsin. Sonra zamanlayıcı süresi dolduktan sonra (10 saniye), ekranınızı base64 verisiyle doldurur (0-9 ve AF'den rastgele karakterler). Çıkmak için Ctrl + C tuşlarına basın.


PoC bash snippet'i de dahil olmak üzere çok iyi çok eksiksiz cevap. Güzel!
fgysin

Bir ağ oturumunun ortasında bir TCP bağlantısı gibi bir işlem donarsa, devam edildiğinde bu ağ oturumu bozulabilir veya düşebilir mi? Bunun için tanımlanmış bir davranış var mı?
CMCDragonkai 11

@ cmcdragonkai çünkü durma işlemi çalışmadığı için, herhangi bir fd'den okuyamaz veya yazamaz, ancak çekirdek bir TCP oturumunda arabellek doluncaya kadar bayt aktarmaya devam eder, yani çekirdek alanı ve kullanıcı alanı arasında aktarım olmaz. donma süreçleri farklıdır kontrol https://www.kernel.org/doc/Documentation/power/freezing-of-tasks.txt
Nizam Mohamed

İşlemi ön plana geri getirdikten sonra TCP bağlantılarının devam edebileceğini öğrendim (zaman aşımları uygulamaya özel, TCP koruma özelliği var ancak uygulama düzeyinde koruma durumu da var). Dondurucu işlemler, bilgisayarın hazırda bekleme veya uyku modunda olduğu anlamına gelir. Bu doğru mu?
CMCDragonkai

Bu betiğin kooperatif olmayan kodlar üzerinde etkisi yoktur: gist.github.com/ceremcem/864dd94b52ffe7b18da29558df4f1f5b
ceremcem

14

Evet, bunu durdurmak için bir işleme STOP sinyali ve ardından devam etmek için bir CONT düğmesine basarak yapabilirsiniz .

kullanımı:

kill -STOP <pid>

kill -CONT <pid>

11

Uygun bir şekilde "donma" tanımının gevşek olması durumunda, renicekomutu kontrol edebilirsiniz .

Renice, çalışan işlemlerin zamanlama önceliğini değiştirmenize izin verir.

İşlemin normal değeri 0'dır. Değerin arttırılması, "neden ilk önce sen gitmiyorsun?" Gibi süreci daha iyi hale getirir. İyi değeri düşürmek, "yolumdan çekilirken acelem var" gibi bir işlemi daha az güzel hale getirir. Güzel değer aralığı -20 ila 19'dur.

Herkes kendi süreçlerini daha iyi hale getirebilir. Yalnızca kök, bir işlemi daha az güzel hale getirebilir veya başka bir kullanıcının işlem güzelliğini değiştirebilir.

Güzel bir değer 19'a ayarlarsanız, yalnızca sistemde başka hiçbir şey istemediğinde çalışır.

İşte benim yerel linux kutumdan bir örnek.

ps -lBir işlem güzel değeri görmek için NI sütununu kullanın ve bakın.

-> ps -l
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY CMD
0 S 29190 402 31146 0 75 0 - 16547 bekleme puanı / 0 bash
0 T 29190 1105 402 0 75 0 - 23980 bitirme puan / 0 vim
0 R 29190 794 402 0 76 0 - 15874 - puan / 0 ps

Koşu renice +10vim sürecine daha düşük bir öncelik sırasında çalışmasına neden olur.

-> renice +10 -p 1105
1105: eski öncelik 0, yeni öncelik 10

-> ps -l
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY CMD
0 S 29190 402 31146 0 76 0 - 16547 bekleme puanı / 0 bash
0 T 29190 1105 402 0 95 10 - 23980 bitirme noktası / 0 vim
0 R 29190 1998 402 0 78 0 - 15874 - puan / 0 ps

"Sistemdeki kimseyi rahatsız etmemek" anlamına gelen "dondurmayı" zorlayabildiğinizi varsayarak, aşağıdaki gibi bir komut dosyası yazabilirsiniz:

renice 20 -p <ilgi alanı>
uyku <belirli bir süre>
renice 0 -p <ilgi alanı>

(root olarak çalıştırmayı unutmayın).


ps -lküçük mavi kutularda güzel görünmek için ilginç sütunlar elde etmek için yukarıdaki çıktıyla bazı özgürlükler aldığımı unutmayın :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.