Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
1 Einleitung
TEIL I: Einstieg in Linux
2 Die Installation
3 Erste Schritte
4 Linux als Workstation für Einsteiger
TEIL II: Grundlagen
5 Kernel
6 Grundlagen aus Anwendersicht
TEIL III: Die Shell
7 Die Shell
8 Reguläre Ausdrücke
9 Konsolentools
10 Die Editoren
11 Shellskriptprogrammierung mit der bash
12 Die C-Shell
TEIL IV: System- & Netzwerkadministration
13 Benutzerverwaltung
14 Grundlegende Verwaltungsaufgaben
15 Netzwerkgrundlagen
16 Anwendersoftware für das Netzwerk
17 Netzwerkdienste
18 Mailserver unter Linux
19 LAMP & Co.
20 DNS-Server
21 Secure Shell
TEIL V: Die grafische Oberfläche
22 Die grafische Oberfläche
23 Window-Manager und Desktops
24 X11-Programme
25 Multimedia und Spiele
TEIL VI: Systeminterna
26 Prozesse und IPC
27 Bootstrap und Shutdown
28 Dateisysteme
29 Virtualisierung und Emulatoren
TEIL VII: Programmierung und Sicherheit
30 Softwareentwicklung
31 Crashkurs in C und Perl
32 Einführung in Computersicherheit
33 Netzwerksicherheit überwachen
TEIL VIII: Anhang
A Lösungen zu den einzelnen Aufgaben
B Kommandoreferenz
C X11-InputDevices
D MBR
E Buch-DVDs
F Glossar
G Literatur
Stichwort
Ihre Meinung?

Spacer
Linux von Johannes Plötner, Steffen Wendzel
Das umfassende Handbuch
Buch: Linux

Linux
Rheinwerk Computing
1282 S., 5., aktualisierte Auflage 2012, geb., mit 2 DVDs
49,90 Euro, ISBN 978-3-8362-1822-1
Pfeil 26 Prozesse und IPC
Pfeil 26.1 Prozessarten
Pfeil 26.1.1 Hintergrundprozesse
Pfeil 26.1.2 Dämonprozesse
Pfeil 26.2 Prozesse in der Shell
Pfeil 26.2.1 Wechseln zwischen Vorder- und Hintergrund
Pfeil 26.2.2 Jobs – behalten Sie sie im Auge
Pfeil 26.2.3 Hintergrundprozesse und Fehlermeldungen
Pfeil 26.2.4 Wann ist es denn endlich vorbei?
Pfeil 26.3 Prozesse und Signale
Pfeil 26.3.1 Das Syscall-Interface
Pfeil 26.3.2 Signale von der Kommandozeile senden: kill
Pfeil 26.3.3 Welche Signale gibt es?
Pfeil 26.3.4 Rechte
Pfeil 26.3.5 In der Praxis: Signale empfangen
Pfeil 26.4 Prozesse finden und beeinflussen
Pfeil 26.4.1 top und htop
Pfeil 26.4.2 ps und pstree
Pfeil 26.4.3 pgrep, pidof und pkill
Pfeil 26.5 Prozesse, Scheduling und Prioritäten
Pfeil 26.5.1 Das Scheduling
Pfeil 26.5.2 nice und renice
Pfeil 26.5.3 Echtzeit-Scheduling unter Linux
Pfeil 26.6 IPC im Detail
Pfeil 26.6.1 Pipes und FIFOs
Pfeil 26.6.2 Semaphore
Pfeil 26.6.3 Message Queues
Pfeil 26.6.4 Shared Memory
Pfeil 26.6.5 Unix-Domain-Sockets
Pfeil 26.7 Zusammenfassung
Pfeil 26.8 Aufgaben

Rheinwerk Computing - Zum Seitenanfang

26.3 Prozesse und SignaleZur nächsten Überschrift

So wie der Prozessor Interrupts als Benachrichtigungen für bestimmte Ereignisse (wie den Ablauf eines Timers oder die Verfügbarkeit aus dem Speicher angeforderter Daten) behandelt, kann ein Prozess über Signale die verschiedensten Ereignisse abfangen.


Rheinwerk Computing - Zum Seitenanfang

26.3.1 Das Syscall-InterfaceZur nächsten ÜberschriftZur vorigen Überschrift

Das eigentliche Versenden und Empfangen von Signalen läuft über den Kernel. Die entsprechenden Schnittstellen sind dabei als Syscalls realisiert:

  • int kill(pid_t pid, int signum);
    Mit dem kill-Syscall kann man Signale versenden. Das Signal selbst wird dabei intern nur über eine Nummer referenziert, wobei dem Programmierer beziehungsweise dem Benutzer in der Shell auch Signalnamen zur Verfügung stehen. Mit pid wird die PID des Prozesses bezeichnet, der das Signal empfangen soll. Wird hier jedoch »0« angegeben, so wird das Signal an alle Prozesse der eigenen Prozessgruppe gesendet. Bei »-1« wird das Signal an alle Prozesse außer init geschickt, und der Wert -PID bezeichnet die Prozessgruppe des Prozesses mit der entsprechenden PID. Ein Beispiel:
  • Listing 26.14 Der Syscall kill

    #include <sys/types.h>
    #include <signal.h>

    int main(int argc, char* argv[])
    {
    kill(1234, SIGTERM);
    return 0;
    }

    Nach der Einbindung der entsprechenden Headerdateien wird dem Prozess mit der PID 1234 hier das SIGTERM-Signal geschickt.

  • sighandler_t signal(int signum, sighandler_t handler);
    Diese Funktion dient dazu, eine Funktion – einen sogenannten Handler (auch Callback) – festzulegen, die beim Empfang des entsprechenden Signals vom Kernel aufgerufen werden soll. Allerdings gibt es auch Signale, die aufgrund ihrer Semantik nicht abgefangen werden können, sondern die direkt vom Kernel bearbeitet werden.

Für den Anwender interessanter als die Frage nach den einzelnen Syscalls ist in den meisten Fällen die Frage nach den unterschiedlichen Signalen. Aus dem ersten Kapitel kennen Sie bereits verschiedene, mehr oder weniger gnadenlos zum Prozess- ende führende Signale: SIGKILL und SIGTERM. Doch zunächst soll kurz besprochen werden, wie man eigentlich Signale von der Kommandozeile senden kann.


Rheinwerk Computing - Zum Seitenanfang

26.3.2 Signale von der Kommandozeile senden: killZur nächsten ÜberschriftZur vorigen Überschrift

Der Benutzer kann mit dem Kommando kill Signale an Prozesse versenden. Hierbei werden wie beim gleichnamigen Syscall der Signaltyp und die Prozess-ID des Zielprozesses beziehungsweise dessen Jobnummer angegeben:

Listing 26.15 Beispielaufruf des kill-Kommandos

$ kill 499
$ kill –9 500
$ kill -SIGKILL 501

[»]Wird kill ohne einen Signalparameter und lediglich mit einer Prozess-ID aufgerufen, so wird das Signal SIGTERM an den Prozess gesendet, das ihn zur Beendigung auffordert, diese aber nicht zwingend erwirkt – denn das Signal kann abgefangen werden.

Rheinwerk Computing - Zum Seitenanfang

26.3.3 Welche Signale gibt es?Zur nächsten ÜberschriftZur vorigen Überschrift

Es gibt also zwei Gruppen von Signalen: Eine Gruppe kann vom Prozess ignoriert beziehungsweise abgefangen werden, die andere nicht. Der Adressat dieser Signale ist viel eher der Kernel, der mit einer bestimmten Aktion gegenüber dem Empfängerprozess reagieren soll. Dies verdeutlichen die folgenden Beispiele:

  • Signal 9, »SIGKILL« oder »KILL«
    Dieses Signal beendet einen Prozess zwingend durch den Kernel.
  • Signal 19, »SIGSTOP« oder »STOP«
    Dieses Signal unterbricht die Verarbeitung eines Prozesses, bis er durch SIGCONT fortgesetzt wird.
  • Signal 18, »SIGCONT« oder »CONT«
    Dieses Signal setzt einen gestoppten Prozess fort.

Im Folgenden sollen abfangbare Signale erläutert werden. Die Liste ist nicht vollständig; es gibt sehr viel mehr als nur die hier genannten Signale. Die wichtigsten Signale können jedoch wie folgt zusammengefasst werden:

  • Signal 1, »SIGHUP« oder »HUP«
    Der Prozess soll sich selbst beenden und neu starten. Dieses Signal wird oftmals benutzt, um Dämonprozesse neu zu starten, damit diese ihre Konfigurationsdaten neu einlesen.
  • Signal 14, »SIGALRM« oder »ALARM«
    Dieses Signal meldet den Ablauf eines Timers, den ein Programmierer mit dem Syscall alarm() starten kann.
  • Signal 15, »SIGTERM« oder »TERM«
    Dieses Signal soll den Prozess dazu bewegen, sich freiwillig zu beenden. Wenn der Computer heruntergefahren wird, sendet der Kernel allen Prozessen solch ein Signal. Daraufhin haben die Prozesse einige Sekunden Zeit, sich zu beenden und beispielsweise Konfigurationsdaten zu speichern, bevor letztendlich das SIGKILL-Signal an alle Prozesse gesendet wird. [Fn. Hierbei sollten Sie beachten, dass nicht alle Prozesse auf das SIGTERM-Signal reagieren. Es liegt im Ermessen des Softwareentwicklers, ob eine entsprechende Signalbehandlungsroutine im Quellcode implementiert wird.]

[+]Aus den Kapiteln zur Shell wissen Sie bereits, dass einige Shells (z. B. die bash) ihre eigenen Implementierungen des kill-Kommandos als Builtin mitbringen. Diese Implementierungen bieten vereinzelt weitere Signaltypen. Die bash zum Beispiel unterstützt über 60 verschiedene Signale.

Eine Liste der von Ihrem kill-Kommando unterstützten Signale können Sie durch den Aufruf von kill -l anzeigen lassen. Das Linux-kill-Kommando kennt darüber hinaus den -L-Parameter für eine tabellarische Ausgabe.


Rheinwerk Computing - Zum Seitenanfang

26.3.4 RechteZur nächsten ÜberschriftZur vorigen Überschrift

Natürlich darf nicht jeder Benutzer fremden Prozessen einfach durch Signale mehr oder weniger unverblümt mitteilen, dass sie doch bitte die wertvolle Rechenzeit freigeben und sich lieber beenden sollen. Dazu muss schon wenigstens die reale oder effektive Benutzer-ID des sendenden Prozesses mit der realen oder gespeicherten Benutzer-ID des Zielprozesses übereinstimmen.

Somit wird gewährleistet, dass ein Benutzer jeweils nur eigene Prozesse »abschießen« kann – mit Ausnahme von root, der ja bekanntlich alles darf.


Rheinwerk Computing - Zum Seitenanfang

26.3.5 In der Praxis: Signale empfangenZur vorigen Überschrift

Im Folgenden sollen noch einmal alle Fakten zu einem abschließenden Beispiel kombiniert werden. Dazu betrachten wir den folgenden Code, der ein Callback handler() zur Behandlung eines Signals über den Syscall signal() beim Kernel registriert:

Listing 26.16 Ein Callback für SIGALRM

#include <signal.h>
#include <stdio.h>

static int x = 0;

void handler(int i)
{
printf("Signal empfangen: %i", i);
x = 1;
return;
}

int main(int argc, char* argv[])
{
typedef void (*sighandler_t)(int);

signal(SIGALRM, &handler);

while(x == 0) {};
return 0;
}

Dem Syscall signal() übergibt man also das abzufangende Signal sowie die Adresse der Funktion, die das Signal behandeln soll. Diese Funktion darf nichts zurückgeben – sie ist vom Typ void – und bekommt als Argument die Nummer des empfangenen Signals übergeben. Das ist insofern sinnvoll, als dass man mit diesem Argument bei einem Handler für mehrere Signale recht einfach überprüfen kann, was genau man da gerade empfangen hat.

Trifft nun ein Signal ein, so wird der Prozess vom Kernel nicht mehr an der alten Stelle – in diesem Fall in der leeren Schleife – fortgesetzt. Stattdessen wird die Funktion handler() aufgerufen, die die Variable x auf »1« setzt. Nach dem Ende der Funktion wird das Programm an der vorherigen Stelle fortgesetzt. Da das Programm in der Schleife unterbrochen wurde, wird es auch dort fortgesetzt – allerdings ist die Abbruchbedingung jetzt erfüllt, und der ganze Prozess kann beendet werden. Die Funktionalität kann man wie folgt testen:

Listing 26.17 Das Beispiel ausprobieren

$ gcc -o test test.c
$ ./test &
[1] 9172
$ kill -SIGALRM %1
$ Signal empfangen: 14
[1]+ Exit 1 ./test

Dabei wird der Sourcecode zuerst kompiliert und anschließend mit dem kaufmännischen »Und« (&) als Hintergrundprozess gestartet. In diesem Augenblick durchläuft das Programm immer wieder die leere Schleife. Erst nachdem wir diesem Job das SIGALRM-Signal geschickt haben, gibt das Programm die Meldung samt der Signalnummer auf der Konsole aus und beendet sich dann, da die Variable x auf »1« gesetzt wurde und somit das Abbruchkriterium für die Schleife erfüllt ist.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Linux
Linux
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Linux Handbuch






 Linux Handbuch


Zum Katalog: Linux Server






 Linux Server


Zum Katalog: Raspberry Pi






 Raspberry Pi


Zum Katalog: Ubuntu 14.04 LTS






 Ubuntu 14.04 LTS


Zum Katalog: Roboter bauen mit Arduino






 Roboter bauen
 mit Arduino


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2012
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de