【问题标题】:Is there a way to make my program work with less code?有没有办法让我的程序用更少的代码工作?
【发布时间】:2013-07-16 08:43:22
【问题描述】:

我为学校作业编写了以下代码 - 它编译并打印所有正确的消息。但只是出于我自己的好奇心,我想知道我的代码是否可以缩短并且仍然有效。我尝试使用“signal”而不是“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;
}

【问题讨论】:

  • 对我来说看起来很短
  • 您可以使用struct sigaction 的数组并仅使用一个处理程序,然后确定它是哪个信号。无论如何,您的代码很好且可读。
  • 信号处理程序可以组合成一个函数来执行switch

标签: c operating-system signals


【解决方案1】:

我想要单个信号处理程序和一个带有 switch-case 的打印函数,用于每种信号消息:

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,包括一个示例。

【讨论】:

    【解决方案2】:
    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 减少代码

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2023-03-28
      • 2019-06-17
      相关资源
      最近更新 更多