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

问题描述

在的CreateProcess(将为pid_t pidArray [])功能,我创建新的进程,如果它是孩子,我打印出来。但在while循环每次我检查killFlag,和我的程序没有efficiant。我怎样才能解决这个问题?感谢您的任何帮助。在我的计划,你可以通过pressing +添加过程或pressing删除它 - 或者只是由pressing Q退出

这是我的code:

 的#include< ncurses.h>
#包括LT&;&unistd.h中GT;
#包括LT&; SYS / wait.h>
#包括LT&;&signal.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&stdlib.h中GT;布尔printAllowed = FALSE;
布尔killFlag = TRUE;
布尔标志= FALSE;
INT processesCount = 0;
INT currentProcessNumber = 0;
静态为const char *颜色[] = {\\ X1B [0米,\\ X1B [31米,\\ X1B [32米,\\ X1B [33米,​​\\ X1B [34米,\\ X1B [35米 \\ X1B [36米,\\ X1B [37米};结构sigaction的printSignal,killSignal;无效allowPrint(INT标志){
  printAllowed = TRUE;
}无效setKillFlag(INT标志){
  killFlag = TRUE;
}INT的CreateProcess(将为pid_t pidArray []){  如果(processesCount→100)返回1;  pidArray [processesCount] =叉();
  processesCount ++;  开关(pidArray [processesCount - 1]){    情况下0:{
      killFlag = FALSE;
      字符的buff [255];
      INT colorNumber =(processesCount大于7)? 0:processesCount;
      sprintf的(BUFF,%sProcess%d个||,颜色[colorNumber],processesCount);
      而(!killFlag){
        usleep(10000);
        如果(printAllowed){
          的for(int i = 0; I<的strlen(浅黄色);我++){
            如果(killFlag){返回-1;};
            的printf(%C,BUFF [I]);
            刷新();
            usleep(50000);
          }
          printAllowed = FALSE;
          //信号母公司这一过程中停止打印
          杀死(getppid(),SIGUSR2);
        }
      }
      返回-1;
    }    情况-1:输出(%!sError,颜色[1]);返回1;    默认:1的回报;
  }
}布尔killProcess(将为pid_t pidArray []){
  如果(processesCount< = 0)返回1;  processesCount--;
  //停止最后一个子进程
  杀死(pidArray [processesCount],SIGUSR2);
  waitpid函数(pidArray [processesCount],NULL,NULL);
  //如果在打印停止现在的过程
  如果(currentProcessNumber> = processesCount){
    currentProcessNumber = 0; //从开始启动
    标志=真实的; //标志按编号最后一道工序
    killFlag = TRUE; //结束的标志打印当前进程
  }  返回1;
}INT controlProcesses(将为pid_t pidArray []){
  halfdelay(1);
  开关((炭)的getchar()){
  情况下=:返回的CreateProcess(pidArray);
  案例' - ':返回killProcess(pidArray);
  案例'Q':返回0;
  默认:1的回报;
  }
}无效killAllProcesses(将为pid_t pidArray []){
  如果(pidArray [ - processesCount]!= 0)
    为(; processesCount> = 0; processesCount - ){
      杀死(pidArray [processesCount],SIGUSR2);
      waitpid函数(pidArray [processesCount],NULL,NULL);
    }
}诠释主(){  initscr的();
  明确();
  NOECHO();
  刷新();
  printSignal.sa_handler = allowPrint;
  的sigaction(SIGUSR1,&安培; printSignal,NULL);  killSignal.sa_handler = setKillFlag;
  的sigaction(SIGUSR2,&安培; killSignal,NULL);  将为pid_t pidArray [100];  而(INT I = controlProcesses(pidArray)){    如果(我== -1)返回0;
    如果(killFlag&安培;&安培; processesCount大于0){//如果当前进程停止印刷
      killFlag = FALSE;
      如果(currentProcessNumber&GT = processesCount - 1)currentProcessNumber = 0; //如果当前进程的数量是最后,从开始开始
      否则,如果currentProcessNumber ++(旗!); //否则,如果上次停止的过程不是最后按编号进入下道工序
      标志= FALSE;
      杀死(pidArray [currentProcessNumber],SIGUSR1); //信号,子进程开始打印
    }
    刷新();
  }
  //停止所有子进程
  killAllProcesses(pidArray);  明确();
  endwin();  返回0;
}


解决方案

killFlags (和 printAllowed )是错误声明。它应该被宣布

 挥发性sig_atomic_t killFlags,printAllowed;

借助预选赛是非常重要的。否则,编译器会假定 killFlags 优化只能明确地改变(它不知道,信号处理程序可以在任何时刻改变它,所以它可以通过保持了优化在寄存器变量,等等...)。

请仔细阅读手册页。

如果你的循环是一个轮询(可能基于的 ...),你可以考虑使用Linux特有的调用。

In createProcess(pid_t pidArray[]) function i create new process and if it's child i print it. But in while loop i everytime check killFlag, and my program no efficiant. How can i fix this issue.? Thank you for any help. In my program you can add process by pressing + or delete it by pressing - or just quit by pressing q.

This is my code:

#include <ncurses.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>

bool printAllowed = false;
bool killFlag = true;
bool flag = false;
int processesCount = 0;
int currentProcessNumber = 0;
static const char *colors[] = { "\x1B[0m", "\x1B[31m","\x1B[32m","\x1B[33m","\x1B[34m","\x1B[35m","\x1B[36m","\x1B[37m" };

struct sigaction printSignal, killSignal;

void allowPrint(int sign){
  printAllowed = true;
}

void setKillFlag(int sign){
  killFlag = true;
}

int createProcess(pid_t pidArray[]){

  if(processesCount > 100) return 1;

  pidArray[processesCount] = fork();
  processesCount++;

  switch(pidArray[processesCount - 1]){

    case 0:{
      killFlag = false;
      char buff[255];
      int colorNumber = (processesCount > 7)? 0 : processesCount;
      sprintf(buff,"%sProcess %d || ", colors[colorNumber], processesCount);
      while(!killFlag) {
        usleep(10000);
        if(printAllowed){
          for(int i = 0; i < strlen(buff); i++){
            if(killFlag) { return -1;};
            printf("%c", buff[i]);
            refresh();
            usleep(50000);
          }
          printAllowed = false;
          // signal to parent that process stop print
          kill(getppid(), SIGUSR2);
        }
      }
      return -1;
    }

    case -1: printf("%sError!", colors[1]); return 1;

    default:  return 1;
  }
}

bool killProcess(pid_t pidArray[]){
  if (processesCount <= 0) return 1;

  processesCount--;
  // stop last child process
  kill(pidArray[processesCount], SIGUSR2);
  waitpid(pidArray[processesCount], NULL, NULL);
  // if the process that printing now stopped
  if (currentProcessNumber >= processesCount){
    currentProcessNumber = 0; // start from beginning
    flag = true;  // flag last process by number
    killFlag = true; // flag of end printing current process
  }

  return 1;
}

int controlProcesses(pid_t pidArray[]){
  halfdelay(1);
  switch((char)getchar()){
  case '=': return createProcess(pidArray);
  case '-': return killProcess(pidArray);
  case 'q': return 0;
  default: return 1;
  }
}

void killAllProcesses(pid_t pidArray[]){
  if(pidArray[--processesCount] != 0)
    for( ;processesCount >= 0; processesCount--){
      kill(pidArray[processesCount],SIGUSR2);
      waitpid(pidArray[processesCount],NULL,NULL);
    }
}

int main(){

  initscr();
  clear();
  noecho();
  refresh();


  printSignal.sa_handler = allowPrint;
  sigaction(SIGUSR1,&printSignal,NULL);

  killSignal.sa_handler = setKillFlag;
  sigaction(SIGUSR2,&killSignal,NULL);

  pid_t pidArray[100];

  while(int i = controlProcesses(pidArray)) {

    if(i == -1) return 0;


    if(killFlag && processesCount > 0){  // if current process stop printing
      killFlag = false;
      if(currentProcessNumber >= processesCount - 1) currentProcessNumber = 0; // if the number of current process is last, start from beginning
      else if(!flag) currentProcessNumber++; // else if last stopped process wasn't the last by number go to next process
      flag = false;
      kill(pidArray[currentProcessNumber], SIGUSR1); // signal to child process start the printing
    }
    refresh();
  }
  // stop all child processes
  killAllProcesses(pidArray);

  clear();
  endwin();

  return 0;
}
解决方案

Your killFlags (and printAllowed) is wrongly declared. It should be declared

volatile sig_atomic_t killFlags, printAllowed;

The volatile qualifier is really important. Otherwise, the compiler would optimize by assuming killFlags can only be explicitly changed (it does not know that a signal handler could change it at any moment, so it could optimize by keeping that variable in a register, etc...).

Read carefully signal(7) man page.

If your loop is a polling event loop (probably based upon poll(2) ...) you might consider using the Linux specific signalfd(2) call.

这篇关于如何设置信号回路检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 02:22
查看更多