0

学校の課題用に次のコードを書きました - すべての正しいメッセージをコンパイルして出力します。しかし、私自身の好奇心のために、コードを短くしてまだ機能するかどうかを知りたい. 「sigaction」ではなく「signal」にしてみましたが、「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;
}
4

2 に答える 2

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)
私の提案:シグナル ハンドラで printf を使用しないでください

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 のドキュメントを参照してください。

于 2013-07-17T17:13:19.080 に答える
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

于 2013-07-17T17:47:56.103 に答える