2013-07-17 31 views
0

我爲學校作業編寫了以下代碼 - 編譯並打印所有正確的消息。但僅僅爲了我自己的好奇心,我想知道我的代碼是否可以縮短並仍然有效。我嘗試了「信號」而不是「sigaction」,但是我聽說「sigaction」比「signal」更優先。另外,這個任務需要3個處理程序。有人可以看看並給我一些提示嗎?謝謝!有沒有辦法讓我的程序使用更少的代碼工作?

#define _POSIX_SOURCE 
#define _BSD_SOURCE 

#include <stdio.h> 
#include <signal.h> 
#include <string.h> 
#include <errno.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 

static void sigHandler_sigusr1(int sig) 
{ 
    printf("Caught SIGUSR1\n"); //sig contains the signal number that was received 
} 

static void sigHandler_sigusr2(int sig) 
{ 
    printf("Caught SIGUSR2\n"); 
} 

static void sigHandler_sigint(int sig) 
{ 
    printf("Caught SIGINT, Existing\n"); 
    exit(EXIT_SUCCESS); 
} 

int main(int argc, char *argv[]) 
{ 
    struct sigaction s1; 
    struct sigaction s2; 
    struct sigaction s3; 
    struct sigaction t; 

    s1.sa_handler = sigHandler_sigusr1; 
    sigemptyset(&s1.sa_mask); 
    s1.sa_flags = 0; 

    s2.sa_handler = sigHandler_sigusr2; 
    sigemptyset(&s2.sa_mask); 
    s2.sa_flags = 0; 

    s3.sa_handler = sigHandler_sigint; 
    sigemptyset(&s3.sa_mask); 
    s3.sa_flags = 0; 

    sigaction(SIGUSR1, &s1, &t); 
    sigaction(SIGUSR2, &s2, &t); 
    sigaction(SIGINT, &s3, &t); 

    kill(getpid(), SIGUSR1); 
    kill(getpid(), SIGUSR2); 
    kill(getpid(), SIGINT); 

    return 0; 
} 
+0

看起來很短,我 –

+1

你可以用'結構sigaction'的陣列,並且只使用一個處理程序,然後確定哪些信號是。反正你的代碼是好的和可讀的。 – GeekFactory

+0

信號處理程序可以組合成一個執行「開關」的單個功能。 –

回答

3

我想一個信號處理程序,並與開關情況下的各種信號的消息的打印功能:

volatile sig_atomic_t flag = 0; 
// single signal handler 
static void sigHandler_sigusr(int sig_no){ 
    flag = sig_no; 
} 

void print_msg(int message_no){ 
    switch(message_no){ 
    case SIGUSR1: printf("Caught SIGUSR1\n"); 
        break; 
    case SIGUSR2: printf("Caught SIGUSR2\n"); 
        break; 
    case SIGINT: printf("Caught SIGINT, Exiting\n"); 
        exit(EXIT_SUCCESS); 
    default: 
      printf("Some other signal"); 
    } 
} 

現在,檢查flag在主,並調用print_msg(flag)。我的意見:avoid using printf in a signal handler

在main()中,爲每種信號註冊單個信號處理函數。

// prepare struct 
struct sigaction sa; 
sa.sa_handler = sigHandler_sigusr; 
sa.sa_flags = SA_RESTART; // Restart functions if 
          // interrupted by handler 

/* // unComment if you wants to block 
    // some signals while one is executing. 
sigset_t set; 
sigemptyset(&set); 
sigaddset(&set, SIGUSR1); 
sigaddset(&set, SIGUSR2); 
sigaddset(&set, SIGINT); 
sa.sa_mask = set; 
*/ 
// Register signals 
sigaction(SIGUSR1, &act, NULL); 
sigaction(SIGUSR2, &act, NULL); 
sigaction(SIGINT, &act, NULL); 

查看sigaction documentation,包括一個例子。

1
static void sigHandlers(int sig) 
{ 
    if (sig == SIGINT) 
    printf("Caught SIGINT, Existing\n"); 
    else if (sig == SIGUSR1) 
    printf("Caught SIGUSR1\n"); 
    else //no need to switch since you have only 3 sig 
    printf("Caught SIGUSR2\n"); 
    exit(EXIT_SUCCESS); 
} 

int main(int argc, char *argv[]) 
{ 
    struct sigaction s[4] = {0}; 

    s[0].sa_handler = sigHandlers; 
    sigemptyset(&(s[0].sa_mask)); 

    memcpy(&s[1], s, sizeof(struct sigaction)); 
    memcpy(&s[2], s, sizeof(struct sigaction)); 

    sigaction(SIGUSR1, &s[0], &s[3]); 
    sigaction(SIGUSR2, &s[1], &s[3]); 
    sigaction(SIGINT, &s[2], &s[3]); 

    kill(getpid(), SIGUSR1); 
    kill(getpid(), SIGUSR2); 
    kill(getpid(), SIGINT); 

    return 0; 
} 

但我敢肯定,你可以減少代碼#define

相關問題