Sök…
Syntax
- osignerat larm (osignerade sekunder);
- int kill (pid_t pid, int sig);
parametrar
| Funktion, parameter (er), returvärde | Beskrivning | 
|---|---|
| alarm() | funktionsnamn | 
| unsigned seconds | Sekunder för att ta upp ett larm eller 0 för att avbryta alla väntande larm | 
| > = 0 | 0 om inget annat larm väntar, annars antalet sekunder som det väntande larmet fortfarande hade öppnat. Denna funktion misslyckas inte. | 
| - | - | 
| kill() | funktionsnamn | 
| pid_t pid | . | 
| int sig | 0 eller signal-ID | 
| 0, -1 | Vid framgång returneras 0, -1 vid fel med inställning av errnotillEINVAL,EPERMellerESRCH. | 
Att höja SIGALARM med standardåtgärden
 Med alarm kan användaren schemalägga SIGALARM signal som ska höjas efter det angivna intervallet. Om användaren inte blockerade, ignorerade eller specificerade uttrycklig signalhanterare för denna signal, kommer standardåtgärden för denna signal att utföras vid ankomst. Per specifikation standardåtgärd för SIGALARM är att avsluta processen: 
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char** argv)
{
    printf("Hello!\n");
    // Set the alarm for five second
    alarm(5); // Per POSIX, this cannot fail
    // Now sleep for 15 seconds
    for (int i = 1; i <= 15; i++)
    {
        printf("%d\n", i);
        sleep(1);
    }
    // And print the message before successful exit
    printf("Goodbye!\n");
    return EXIT_SUCCESS;
}
Denna utgångar:
Hello!
1
2
3
4
5
[2]    35086 alarm      ./a.out
Ställa in signalhanterare med hjälp av signering och höja signaler med höjning
 För att ett program ska reagera på en viss signal, annat än att använda standardåtgärder, kan anpassad signalhanterare installeras med sigaction . sigaction får tre argument - signal att agera på, pekare till sigaction_t struktur som, om inte NULL , beskriver nytt beteende och pekare till sigaction_t som, om inte NULL kommer att fyllas med det gamla beteendet (så man kan återställa det). Att höja signaler i samma process kan göras med raise . Om mer kontroll behövs (för att skicka signalen till någon annan process kan kill eller pthread_kill användas, som accepterar destinationsprocess-id eller tråd-id). 
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Signals are numbered from 1, signal 0 doesn't exist
volatile sig_atomic_t last_received_signal = 0;
// Signal handler, will set the global variable
// to indicate what is the last signal received.
// There should be as less work as possible inside
// signal handler routine, and one must take care only
// to call reentrant functions (in case of signal arriving
// while program is already executing same function)
void signal_catcher(int signo, siginfo_t *info, void *context)
{
    last_received_signal = info->si_signo;
}
int main (int argc, char** argv)
{
    // Setup a signal handler for SIGUSR1 and SIGUSR2
    struct sigaction act;
    memset(&act, 0, sizeof act);
    // sigact structure holding old configuration
    // (will be filled by sigaction):
    struct sigaction old_1;
    memset(&old_1, 0, sizeof old_1);
    struct sigaction old_2;
    memset(&old_2, 0, sizeof old_2);
    act.sa_sigaction = signal_catcher;
    // When passing sa_sigaction, SA_SIGINFO flag
    // must be specified. Otherwise, function pointed
    // by act.sa_handler will be invoked
    act.sa_flags = SA_SIGINFO;
    if (0 != sigaction(SIGUSR1, &act, &old_1))
    {
        perror("sigaction () failed installing SIGUSR1 handler");
        return EXIT_FAILURE;
    }
    if (0 != sigaction(SIGUSR2, &act, &old_2))
    {
        perror("sigaction() failed installing SIGUSR2 handler");
        return EXIT_FAILURE;
    }
    // Main body of "work" during which two signals
    // will be raised, after 5 and 10 seconds, and which
    // will print last received signal
    for (int i = 1; i <= 15; i++)
    {
        if (i == 5)
        {
            if (0 != raise(SIGUSR1))
            {
                perror("Can't raise SIGUSR1");
                return EXIT_FAILURE;
            }
        }
        if (i == 10)
        {
            if (0 != raise(SIGUSR2))
            {
                perror("Can't raise SIGUSR2");
                return EXIT_FAILURE;
            }
        }
        printf("Tick #%d, last caught signal: %d\n",
            i, last_received_signal);
        sleep(1);
    }
    // Restore old signal handlers
    if (0 != sigaction(SIGUSR1, &old_1, NULL))
    {
        perror("sigaction() failed restoring SIGUSR1 handler");
        return EXIT_FAILURE;
    }
    if (0 != sigaction(SIGUSR2, &old_2, NULL))
    {
        perror("sigaction() failed restoring SIGUSR2 handler");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
Denna utgångar:
Tick #1, last caught signal: 0
Tick #2, last caught signal: 0
Tick #3, last caught signal: 0
Tick #4, last caught signal: 0
Tick #5, last caught signal: 30
Tick #6, last caught signal: 30
Tick #7, last caught signal: 30
Tick #8, last caught signal: 30
Tick #9, last caught signal: 30
Tick #10, last caught signal: 31
Tick #11, last caught signal: 31
Tick #12, last caught signal: 31
Tick #13, last caught signal: 31
Tick #14, last caught signal: 31
Tick #15, last caught signal: 31
En process som begår självmord med kill ()
 En process kan (försöka) skicka en signal till någon annan process med funktionen kill() . 
 För att göra det måste sändningsprocessen kända mottagningsprocessen PID. Eftersom, utan att införa ett lopp, kan en process bara vara säker på sin egen PID (och dess barns PID), det enklaste exemplet för att demonstrera användningen av kill() är att låta en process skicka en signal till sig själv. 
 Nedanför ett exempel på en process som inleder sin egen avslutning genom att skicka sig själv en kill-signal ( SIGKILL ): 
#define _POSIX_C_SOURCE 1
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
int main (void)
{
  pid_t pid = getpid(); /* Get my iown process ID. */
  kill(pid, SIGKILL); /* Send myself a KILL signal. */
  puts("Signal delivery initiated.");  /* Although not guaranteed, 
                                  practically the program never gets here. */
  pause(); /* Wait to die. */
  puts("This never gets printed.");
}
Produktion:
Killed
(... eller lika, beroende på implementeringen)
Hantera SIGPIPE som genererats genom att skriva () på ett tråd-säkert sätt
 När write() krävs för ett namngivet eller icke namngivet rör eller strömuttag vars läsänd är stängd, händer två saker: 
-  SIGPIPEsignal skickas till processen som kallaswrite()
-  SIGPIPEsignal skickas till tråden som kallaswrite()
-  EPIPEfelet returneras avwrite()
 Det finns flera sätt att hantera SIGPIPE : 
-  För uttag kan SIGPIPEinaktiveras genom att ställa in plattformspecifika alternativ somMSG_NOSIGNALi Linux ochSO_NOSIGPIPEi BSD (fungerar endast försend, men inte förwrite). Detta är inte bärbart.
-  För FIFO: er (namngivna rör) kommer SIGPIPEinte att genereras om författaren använderO_RDWRistället förO_WRONLY, så attO_WRONLYalltid öppnas. Men detta inaktiverarEPIPEockså.
-  Vi kan ignorera SIGPIPEeller ställa in global hanterare. Detta är en bra lösning, men det är inte acceptabelt om du inte kontrollerar hela applikationen (t.ex. skriver du ett bibliotek).
-  Med de senaste POSIX-versionerna kan vi använda det faktum att SIGPIPEskickas till tråden som kallaswrite()och hanterar den med hjälp av synkron signalhanteringsteknik.
 Koden nedan visar SIGPIPE hantering för POSIX.1-2004 och senare. 
Det är inspirerat av det här inlägget :
-  Lägg först SIGPIPEtill signalmask för aktuell tråd medpthread_sigmask().
-  Kontrollera om SIGPIPEredan finns i väntande medsigpending().
-  Ring write(). Om lässlutet är stängt läggsSIGPIPEtill pågåendeEPIPEochEPIPEreturneras.
-  Om write()returneradeEPIPE, ochSIGPIPEinte redan väntade innanwrite(), ta bort den från väntandesigtimedwait()medsigtimedwait().
-  Återställ original signalmask med pthread_sigmask().
Källkod:
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <sys/signal.h>
ssize_t safe_write(int fd, const void* buf, size_t bufsz)
{
    sigset_t sig_block, sig_restore, sig_pending;
    sigemptyset(&sig_block);
    sigaddset(&sig_block, SIGPIPE);
    /* Block SIGPIPE for this thread.
     *
     * This works since kernel sends SIGPIPE to the thread that called write(),
     * not to the whole process.
     */
    if (pthread_sigmask(SIG_BLOCK, &sig_block, &sig_restore) != 0) {
        return -1;
    }
    /* Check if SIGPIPE is already pending.
     */
    int sigpipe_pending = -1;
    if (sigpending(&sig_pending) != -1) {
        sigpipe_pending = sigismember(&sig_pending, SIGPIPE);
    }
    if (sigpipe_pending == -1) {
        pthread_sigmask(SIG_SETMASK, &sig_restore, NULL);
        return -1;
    }
    ssize_t ret;
    while ((ret = write(fd, buf, bufsz)) == -1) {
        if (errno != EINTR)
            break;
    }
    /* Fetch generated SIGPIPE if write() failed with EPIPE.
     *
     * However, if SIGPIPE was already pending before calling write(), it was
     * also generated and blocked by caller, and caller may expect that it can
     * fetch it later. Since signals are not queued, we don't fetch it in this
     * case.
     */
    if (ret == -1 && errno == EPIPE && sigpipe_pending == 0) {
        struct timespec ts;
        ts.tv_sec = 0;
        ts.tv_nsec = 0;
        int sig;
        while ((sig = sigtimedwait(&sig_block, 0, &ts)) == -1) {
            if (errno != EINTR)
                break;
        }
    }
    pthread_sigmask(SIG_SETMASK, &sig_restore, NULL);
    return ret;
}