信号处理问题 [英] Issues with signal handling

查看:165
本文介绍了信号处理问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

使用sigaction的多个信号处理程序的问题

我试图实际研究多进程系统中的信号处理行为。我有一个系统,其中有三个信号生成过程生成类型SIGUSR1和SIGUSR1的信号。我有两个处理程序处理特定类型的信号。我有另一个监控过程,也接收信号,然后做它的工作。我有一个问题。每当我的信号处理过程产生特定类型的信号时,它被发送到过程组,以便它被信号处理过程以及监视过程接收。

I am trying to actually study the signal handling behavior in multiprocess system. I have a system where there are three signal generating processes generating signals of type SIGUSR1 and SIGUSR1. I have two handler processes that handle a particular type of signal. I have another monitoring process that also receives the signals and then does its work. I have a certain issue. Whenever my signal handling processes generate a signal of a particular type, it is sent to the process group so it is received by the signal handling processes as well as the monitoring processes.

每当调用监视和信号处理过程的信号处理器时,我都打印出来指示信号处理。我期待一个统一的系列调用监听和处理过程的信号处理程序。然而,看看输出我可以看到像在开始监视和信号处理过程的信号处理程序统一调用。

Whenever the signal handlers of monitoring and signal handling processes are called, I have printed to indicate the signal handling. I was expecting a uniform series of calls for the signal handlers of the monitoring and handling processes. However, looking at the output I could see like at the beginning the monitoring and signal handling processes's signal handlers are called uniformly.

然而,在我可以看到像信号处理程序进程

However, after I could see like signal handler processes handlers being called in a burst followed by the signal handler of monitoring process being called in a burst.

这是我的代码和输出

#include <iostream>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <signal.h>
#include <cstdio>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define NUM_SENDER_PROCESSES 3
#define NUM_HANDLER_PROCESSES 4
#define NUM_SIGNAL_REPORT 10
#define MAX_SIGNAL_COUNT 100000

using namespace std;

volatile int *usrsig1_handler_count;
volatile int *usrsig2_handler_count;
volatile int *usrsig1_sender_count;
volatile int *usrsig2_sender_count;
volatile int *lock_1;
volatile int *lock_2;
volatile int *lock_3;
volatile int *lock_4;
volatile int *lock_5;
volatile int *lock_6;


//Used only by the monitoring process
volatile int monitor_count;
volatile int usrsig1_monitor_count;
volatile int usrsig2_monitor_count;
double time_1[NUM_SIGNAL_REPORT];
double time_2[NUM_SIGNAL_REPORT];

//Used only by the main process
int total_signal_count;

//For shared memory
int shmid;
const int shareSize = sizeof(int) * (10);



double timestamp() {
  struct timeval tp;
  gettimeofday(&tp, NULL);
  return (double)tp.tv_sec + tp.tv_usec / 1000000.;
}


pid_t senders[NUM_SENDER_PROCESSES];
pid_t handlers[NUM_HANDLER_PROCESSES];
pid_t reporter;

void signal_catcher_1(int);
void signal_catcher_2(int);
void signal_catcher_int(int);
void signal_catcher_monitor(int);
void signal_catcher_main(int);

void terminate_processes() {
  //Kill the child processes
  int status;
  cout << "Time up terminating the child processes" << endl;
  for(int i=0; i<NUM_SENDER_PROCESSES; i++) {
    kill(senders[i],SIGKILL);
  }
  for(int i=0; i<NUM_HANDLER_PROCESSES; i++) {
    kill(handlers[i],SIGKILL);
  }
  kill(reporter,SIGKILL);

  //Wait for the child processes to finish
  for(int i=0; i<NUM_SENDER_PROCESSES; i++) {
    waitpid(senders[i], &status, 0);
  }
  for(int i=0; i<NUM_HANDLER_PROCESSES; i++) {
    waitpid(handlers[i], &status, 0);
  }
  waitpid(reporter, &status, 0);
}

int main(int argc, char *argv[]) {
  if(argc != 2) {
    cout << "Required parameters missing. " << endl;
    cout << "Option 1 = 1 which means run for 30 seconds" << endl;
    cout << "Option 2 = 2 which means run until 100000 signals" << endl;
    exit(0);
  }

  int option = atoi(argv[1]);

  pid_t pid;

  if(option == 2) {
    if(signal(SIGUSR1, signal_catcher_main) == SIG_ERR) {
      perror("1");
      exit(1);
    }

    if(signal(SIGUSR2, signal_catcher_main) == SIG_ERR) {
      perror("2");
      exit(1);
    }
  } else {
    if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
      perror("1");
      exit(1);
    }

    if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
      perror("2");
      exit(1);
    }

  }

  if(signal(SIGINT, signal_catcher_int) == SIG_ERR) {
    perror("3");
    exit(1);
  }

  ///////////////////////////////////////////////////////////////////////////////////////
  ////////////////////// Initializing the shared memory /////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////
  cout << "Initializing the shared memory" << endl;
  if ((shmid=shmget(IPC_PRIVATE,shareSize,IPC_CREAT|0660))< 0) {
    perror("shmget fail");
    exit(1);
  }  

  usrsig1_handler_count = (int *) shmat(shmid, NULL, 0);
  usrsig2_handler_count = usrsig1_handler_count + 1;
  usrsig1_sender_count = usrsig2_handler_count + 1;
  usrsig2_sender_count = usrsig1_sender_count + 1;
  lock_1 = usrsig2_sender_count + 1;
  lock_2 = lock_1 + 1;
  lock_3 = lock_2 + 1;
  lock_4 = lock_3 + 1;
  lock_5 = lock_4 + 1;
  lock_6 = lock_5 + 1;

  //Initialize them to be zero
  *usrsig1_handler_count = 0;
  *usrsig2_handler_count = 0;
  *usrsig1_sender_count = 0;
  *usrsig2_sender_count = 0;
  *lock_1 = 0;
  *lock_2 = 0;
  *lock_3 = 0;
  *lock_4 = 0;
  *lock_5 = 0;
  *lock_6 = 0;


  cout << "End of initializing the shared memory" << endl;
  /////////////////////////////////////////////////////////////////////////////////////////////
  /////////////////// End of initializing the shared memory ///////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////////


  ///////////////////////////////////////////////////////////////////////////////////////////
  /////////////////////////////Registering the signal handlers///////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////
  cout << "Registering the signal handlers" << endl;
  for(int i=0; i<NUM_HANDLER_PROCESSES; i++) {
    if((pid = fork()) == 0) {
      if(i%2 == 0) {
        struct sigaction action;
        action.sa_handler = signal_catcher_1;
        sigset_t block_mask;
        action.sa_flags = 0;
        sigaction(SIGUSR1,&action,NULL);

        if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
          perror("2");
          exit(1);
        }

      } else {
        if(signal(SIGUSR1 ,SIG_IGN) == SIG_ERR) {
          perror("1");
          exit(1);
        }

        struct sigaction action;
        action.sa_handler = signal_catcher_2;
        action.sa_flags = 0;
        sigaction(SIGUSR2,&action,NULL);

      }

      if(signal(SIGINT, SIG_DFL) == SIG_ERR) {
        perror("2");
        exit(1);
      }

      while(true) {
        pause();
      }
      exit(0);

    } else {
      //cout << "Registerd the handler " << pid << endl;
      handlers[i] = pid;
    }
  }
  cout << "End of registering the signal handlers" << endl;

  /////////////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////////End of registering the signal handlers //////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////////////////


  ////////////////////////////////////////////////////////////////////////////////////////////////////
  ///////////////////////////Registering the monitoring process //////////////////////////////////////
  ////////////////////////////////////////////////////////////////////////////////////////////////////
  cout << "Registering the monitoring process" << endl;
  if((pid = fork()) == 0) {
    struct sigaction action;
    action.sa_handler = signal_catcher_monitor;
    sigemptyset(&action.sa_mask);
    sigset_t block_mask;
    sigemptyset(&block_mask);
    sigaddset(&block_mask,SIGUSR1);
    sigaddset(&block_mask,SIGUSR2);
    action.sa_flags = 0;
    action.sa_mask = block_mask;
    sigaction(SIGUSR1,&action,NULL);
    sigaction(SIGUSR2,&action,NULL);


    if(signal(SIGINT, SIG_DFL) == SIG_ERR) {
      perror("2");
      exit(1);
    }

    while(true) {
      pause();
    }
    exit(0);

  } else {
    cout << "Monitor's pid is " << pid << endl;
    reporter = pid;
  }
  cout << "End of registering the monitoring process" << endl;

  /////////////////////////////////////////////////////////////////////////////////////////////////////
  ////////////////////////End of registering the monitoring process////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////////////////


  //Sleep to make sure that the monitor and handler processes are well initialized and ready to handle signals
  sleep(5);


  //////////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////Registering the signal generators///////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////////////////
  cout << "Registering the signal generators" << endl;
  for(int i=0; i<NUM_SENDER_PROCESSES; i++) {

    if((pid = fork()) == 0) {

      if(signal(SIGUSR1, SIG_IGN) == SIG_ERR) {
        perror("1");
        exit(1);
      }

      if(signal(SIGUSR2, SIG_IGN) == SIG_ERR) {
        perror("2");
        exit(1);
      }

      if(signal(SIGINT, SIG_DFL) == SIG_ERR) {
        perror("2");
        exit(1);
      }

      srand(i);        
      while(true) {
        int signal_id = rand()%2 + 1;

        if(signal_id == 1) {
          killpg(getpgid(getpid()), SIGUSR1);
          while(__sync_lock_test_and_set(lock_4,1) != 0) {
          }
          (*usrsig1_sender_count)++;
          *lock_4 = 0;
        } else {
          killpg(getpgid(getpid()), SIGUSR2);
          while(__sync_lock_test_and_set(lock_5,1) != 0) {
          }
          (*usrsig2_sender_count)++;
          *lock_5=0;
        }       
        int r = rand()%10 + 1;
        double s = (double)r/100;
        sleep(s);
      }

      exit(0); 
    } else {
      //cout << "Registered the sender " << pid << endl;
      senders[i] = pid;
    } 
  }

  //cout << "End of registering the signal generators" << endl;
  /////////////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////End of registering the signal generators///////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////////////////


  //Either sleep for 30 seconds and terminate the program or if the number of signals generated reaches 10000, terminate the program
  if(option = 1) {
    sleep(90);
    terminate_processes(); 
  } else {
    while(true) {
      if(total_signal_count >= MAX_SIGNAL_COUNT) {
        terminate_processes();
      } else {
        sleep(0.001);
      }
    }
  }
}




void signal_catcher_1(int the_sig) {
  while(__sync_lock_test_and_set(lock_1,1) != 0) {
  }
  (*usrsig1_handler_count) = (*usrsig1_handler_count) + 1;
  cout << "Signal Handler 1 " << *usrsig1_handler_count << endl;
  __sync_lock_release(lock_1);
}


void signal_catcher_2(int the_sig) {
   while(__sync_lock_test_and_set(lock_2,1) != 0) {
   }
   (*usrsig2_handler_count) = (*usrsig2_handler_count) + 1;
   __sync_lock_release(lock_2);

}

void signal_catcher_main(int the_sig) {
  while(__sync_lock_test_and_set(lock_6,1) != 0) {
  }
  total_signal_count++;
  *lock_6 = 0;
}


void signal_catcher_int(int the_sig) {
  for(int i=0; i<NUM_SENDER_PROCESSES; i++) {
    kill(senders[i],SIGKILL);
  }

  for(int i=0; i<NUM_HANDLER_PROCESSES; i++) {
    kill(handlers[i],SIGKILL);
  }

  kill(reporter,SIGKILL);

  exit(3);
}

void signal_catcher_monitor(int the_sig) {
  cout << "Monitoring process " << *usrsig1_handler_count << endl;
}

以下是输出的初始段

Monitoring process 0
Monitoring process 0
Monitoring process 0
Monitoring process 0
Signal Handler 1 1
Monitoring process 2
Signal Handler 1 2
Signal Handler 1 3
Signal Handler 1 4
Monitoring process 4
Monitoring process Signal Handler 1 6
Signal Handler 1 7
Monitoring process 7
Monitoring process 8
Monitoring process 8
Signal Handler 1 9
Monitoring process 9
Monitoring process 9
Monitoring process 10
Signal Handler 1 11
Monitoring process 11
Monitoring process 12
Signal Handler 1 13
Signal Handler 1 14
Signal Handler 1 15
Signal Handler 1 16
Signal Handler 1 17
Signal Handler 1 18
Monitoring process 19
Signal Handler 1 20
Monitoring process 20
Signal Handler 1 21
Monitoring process 21
Monitoring process 21
Monitoring process 22
Monitoring process 22
Monitoring process 23
Signal Handler 1 24
Signal Handler 1 25
Monitoring process 25
Signal Handler 1 27
Signal Handler 1 28
Signal Handler 1 29

以下是当信号处理程序处理信号处理程序时突然调用的段

Here is the segment when the signal handler processes signal handlers are called in a burst

Signal Handler 1 456
Signal Handler 1 457
Signal Handler 1 458
Signal Handler 1 459
Signal Handler 1 460
Signal Handler 1 461
Signal Handler 1 462
Signal Handler 1 463
Signal Handler 1 464
Signal Handler 1 465
Signal Handler 1 466
Signal Handler 1 467
Signal Handler 1 468
Signal Handler 1 469
Signal Handler 1 470
Signal Handler 1 471
Signal Handler 1 472
Signal Handler 1 473
Signal Handler 1 474
Signal Handler 1 475
Signal Handler 1 476
Signal Handler 1 477
Signal Handler 1 478
Signal Handler 1 479
Signal Handler 1 480
Signal Handler 1 481
Signal Handler 1 482
Signal Handler 1 483
Signal Handler 1 484
Signal Handler 1 485
Signal Handler 1 486
Signal Handler 1 487
Signal Handler 1 488
Signal Handler 1 489
Signal Handler 1 490
Signal Handler 1 491
Signal Handler 1 492
Signal Handler 1 493
Signal Handler 1 494
Signal Handler 1 495
Signal Handler 1 496
Signal Handler 1 497
Signal Handler 1 498
Signal Handler 1 499
Signal Handler 1 500
Signal Handler 1 501
Signal Handler 1 502
Signal Handler 1 503
Signal Handler 1 504
Signal Handler 1 505
Signal Handler 1 506

这里是当监视处理信号处理程序时突发

Here is the segment when the monitoring processes signal handlers are called in a burst

Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140
Monitoring process 140

为什么后来不统一。为什么它们被突然调用?

Why isn't it uniform afterwards. Why are they called in a burst?

推荐答案

看起来你正在看到操作系统进程调度的影响。这里是维基百科的文章,解释各种类型的时间安排: http://en.wikipedia.org/ wiki / Scheduling_(计算)

It looks like you are seeing the effects of operating system process scheduling. Here is the wikipedia article explaining various types of scheduling: http://en.wikipedia.org/wiki/Scheduling_(computing).

输出从短脉冲切换到长脉冲的原因很可能是由于操作系统正在尝试以最小化在高度活动的进程之间切换所花费的时间。

The reason the output switches from short bursts to long bursts is most likely due to the fact that the operating system is trying to minimize the time spent switching between highly active processes.

这篇关于信号处理问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆