Programuję, piszę albo czytam, a tu nagle komputer zauważalnie się przycina albo przeglądarka ma kłopoty z otwieraniem stron. Całkiem częstą przyczyną bywa uruchomienie się jakiegoś pracochłonnego zadania z crona (czy to systemowego, czy to jakiegoś zdefiniowanego przeze mnie backupu albo innej synchronizacji repozytoriów).
Odruchowo narzuca się program nice
(obniżający priorytet wybranych
procesów) ale w desktopowej praktyce jego efekty bywają nieznaczne,
bo bardziej niż CPU liczy się obciążenie dysku czy sieci albo
zużycie pamięci.
Pełniejsze rozwiązanie może wyglądać następująco (prawdziwym
wykonywanym poleceniem jest tutaj hg pull pitagoras
czyli
dociągnięcie zmian w repozytorium Mercuriala):
ulimit -d 524288 -v 1048576 chronic nice ionice -c3 trickle -s -d 128 -u 32 \ hg pull pitagoras
Krótkie wyjaśnienie poszczególnych komend poniżej ale najpierw uwaga
wstępna: poza ulimit
, pozostałe programy działają na zasadzie coś
konfiguruję, po czym uruchamiam program zadany jako parametr w
odpowiednio przygotowanym środowisku. Innymi słowy, powyżej
program chronic
uruchamia program nice
, który uruchamia program
ionice
, który odpala program trickle
, który wreszcie wywołuje
właściwą komendę.
ulimit
ulimit
jest wbudowaną komendą basha (i innych shelli). Pozwala
ustawić ograniczenia na zasoby systemowe wykorzystywane przez
uruchamiane później z tego shella procesy - rozmiary różnego typu
pamięci, ilość podprocesów, ilość otwartych plików i parę
innych. Powyżej ustawiłem maksymalny rozmiar segmentu danych na
524288kB (czyli 512MB) i maksymalny rozmiar pamięci wirtualnej na 1GB.
Ustawienia ulimit
są trwałe (na poziomie shella), dotyczą
wszystkich później uruchamianych komend.
Ustawiając zbyt małe rozmiary możemy podziwiać efekty w stylu:$ ulimit -v 512 # albo np. ulimit -s 32 $ ls Segmentation faultalbo (w innym shellu):$ ulimit -d 64 $ ls bash: xmalloc: ../bash/variables.c:2915: cannot allocate 5064 bytes (5443584 bytes allocated)Bywało to sposobem na (niezbyt wyrafinowane) dowcipy przy pracy na wspólnym terminalu…
Szczegółowy opis ulimit
można znaleźć w man bash
(albo
man dash
, albo man zshbuiltins
, ...) a aktualny stan
rzeczy sprawdzić uruchamiając ulimit -a
.
chronic
chronic
jest tu troszkę z innej bajki (nie dotyczy ograniczania
zasobów) ale często przydaje się w tych samych skryptach. Jego jedynym
zadaniem jest ukrycie tekstu wypisanego przez uruchomiony program na
standardowe wyjście - o ile program nie zgłosił błędu (rozpoznawanego
po statusie wykonania).
Szczególnie przydatne jest to przy uruchamianiu z crona gadatliwych programów - cron wysyła maila, o ile odpalany program coś wypisywał, dzięki chronicowi tego maila nie będzie. Chyba że coś pójdzie źle, wtedy pojawi się komplet informacji.
Prosty przykład jak to działa:
marcink@banach:~/devel/mekk_feeds$ hg pull platon pulling from ssh://platon/devel/mekk_feeds searching for changes no changes found marcink@banach:~/devel/mekk_feeds$ chronic hg pull platon marcink@banach:~/devel/mekk_feeds$ chronic hg pull palton abort: repository palton not found!
W bieżącym Ubuntu chronic
jest dostępny w pakiecie moreutils
.
W starszych wersjach można zainstalować
ręcznie wersję 0.43 lub nowszą.
Na przykład tak:
$ sudo apt-get install dpkg-dev fakeroot build-essential debhelper # narzędzia do robienia pakietów $ sudo apt-get install docbook2x docbook-xml libipc-run-perl # wymagane przez moreutils $ wget https://launchpad.net/ubuntu/+archive/primary/+files/moreutils_0.45.dsc $ wget https://launchpad.net/ubuntu/+archive/primary/+files/moreutils_0.45.tar.gz $ dpkg-source -x moreutils_0.45.dsc $ cd moreutils_0.45 $ dpkg-buildpackage -b $ cd .. $ sudo dpkg -i moreutils_0.45_amd64.deb
nice
Standardowy program do uruchamiania zadanego jako parametr zadania ze zmienionym priorytetem. W domyślnej wersji (bez parametrów) priorytet obniża o 10. Np. przy
$ nice apt-get upgrade
aktualizator będzie mniej agresywnie zajmować procesor.
Efekty nice
są dość wyraźne gdy działa równocześnie kilka
programów mocno obciążających procesor (np. obliczeniowych). Przy
aplikacjach intensywnie korzystających z wejścia/wyjścia (sieci,
plików) efekt ten jest znacznie zaburzony (także ze względu
na wpływ I/O na scheduler), choć i na wejście/wyjście nice ma pewien wpływ.
Parą dla
nice
jest programrenice
zmieniający priorytet działającego procesu/procesów.
Na Debianie i Ubuntu nice
jest częścią pakietu coreutils
.
ionice
ionice
konfiguruje priorytet programu przy dostępie do dysku.
Użyte wyżej ionice -c3
oznacza tzw. tryb Idle, w którym
program może czytać/pisać tylko gdy dysk nie jest używany
przez żadną inną aplikację. Bardziej subtelne byłoby
ionice -c2 -n7
(tryb Best Effort, czyli normalny, z
priorytetem 7, czyli najniższym).
ionice -c2 -n7 \ unison /piosenki ssh://pitagoras/piosenki
Szczegółowe informacje można znaleźć w man ionice
.
ionice
można też używać jak renice, tj. do zmiany charakterystyk działającego programu (zadając opcję-p <pid>
).
Na Debianie i Ubuntu ionice
jest częścią pakietu util-linux
.
trickle
trickle
ogranicza wykorzystanie pasma sieciowego przez pojedynczy
program. Podane wyżej opcje oznaczają co najwyżej 128KB/s przy ściąganiu
(-d 128
) i co najwyżej 32KB/s przy uploadzie (-u 32
).
Prosty przykład: gdy bez żadnych ograniczeń duży download skutecznie wykorzystuje pasmo:
trickle
potrafi utrzymać program w ryzach:
trickle -d 128 -u 32 -s \ wget http://atlas/iso/ubuntu-11.04.iso
Flaga -s
ogranicza limity do pojedynczego uruchomionego programu
(bez niej program próbuje komunikować się z demonem trickled
pozwalającym na nakładanie także zbiorczych ograniczeń na wszystkie
programy uruchomione z trickle
, może to być przydatne przy odpalaniu
jakichś grup procesów ale w normalnej sytuacji jest raczej zbędne).
Na Debianie i Ubuntu trickle
jest częścią pakietu trickle
.
Dodatkowe możliwości
I jeszcze o pewnych elementach nie użytych w początkowym przykładzie.
taskset
Polecenie taskset
pozwala przypisać uruchamiane (albo działające)
zadanie do konkretnego procesora (a raczej rdzenia) - tzw. CPU
affinity. Można to wykorzystać np. przypisując wszystkie zadania
jakiejś klasy do jednego procesora, by pozostałe CPU pozostały wolne.
Prosty przykład (procesory są liczone od 00
):
$ taskset 01 mencoder ... $ taskset 01 lame ....
(oba programy będą działać na drugim procesorze/rdzeniu zostawiając pierwszy w spokoju).
Na Debianie i Ubuntu taskset
jest częścią pakietu util-linux
.
TMPDIR
Zdarza się, że ten czy inny program doprowadzi do problemów ze stabilnością
desktopu zapychając katalog /tmp
. Można go przekierować gdzie
indziej ustawiając (przed jego uruchomieniem) zmienną środowiskową TMPDIR
:
export TMPDIR=$HOME/tmp jakis_tam_program
quota
quota
pozwala nakładać limity wykorzystania miejsca na dyskach - na
poziomie użytkowników lub ich grup. Tradycyjnie służy do ograniczania
ludzkich użytkowników na maszynach wielodostępnych ale można się nim
posłużyć i przy limitowaniu miejsca skonsumowanego (np. w /var
)
przez niektóre specjalne konta systemowe.