问题描述
在的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.
这篇关于如何设置信号回路检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!