我们正在尝试使用sigaction和setitimer从我们的三个函数中的while(1)循环中控制,我们现在面临的问题是只生成一次SIGALRM并且下一次它不生成即我们能够从fun1()的while(1)而不是fun2()的while(1)获取控制权。 你能否提出解决这个问题的方法。请找下面的代码。
#define INTERVAL 500
void fun1();
void fun2();
void fun3();
void timer_handler(int );
struct itimerval it_val;
int count=0;
void timer_handler (int signum)
{
L1:
printf(“\nScheduler Called .. Calling Fun1″);
if(count==0){
count++;
fun1();
}
printf(“\nScheduler Called .. Calling Fun2″);
if(count==1){
count++;
fun2();
}
printf(“\nScheduler Called .. Calling Fun3″);
if(count==2){
count++;
fun3();
}
count=0;
goto L1;
}
void fun1()
{
struct sigaction sa;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
/* Configure the timer to expire */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a timer. It counts down whenever this process is*/
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1){
printf(“\nfun1″);
}
}
void fun2()
{
struct sigaction sa;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
/* Configure the timer to expire */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a timer. It counts down whenever this process is*/
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1){
printf(“\nfun2″);
}
}
void fun3()
{
struct sigaction sa;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
/* Configure the timer to expire */
it_val.it_value.tv_sec = INTERVAL/1000;
it_val.it_value.tv_usec = (INTERVAL*1000) % 1000000;
it_val.it_interval.tv_sec = INTERVAL/1000;;
it_val.it_interval.tv_usec=(INTERVAL*1000) % 1000000;
/* Start a timer. It counts down whenever this process is*/
sigaction (SIGALRM, &sa, NULL);
setitimer (ITIMER_REAL, &it_val, NULL);
while (1){
printf(“\nfun3″);
}
}
int main(){
timer_handler(1);
return 0;
}
答案 0 :(得分:1)
当信号传递时,它会自动屏蔽,直到动作函数返回。
一般情况下,您希望信号动作功能绝对最小。你所编写的内容实际上是一个递归动作函数,其中包含大部分程序。即使它确实有效,你也会吃堆栈,直到没有剩下!
章节和诗句:来自sigaction()
的POSIX:
当信号被安装的信号捕获功能捕获时 sigaction(),计算并安装一个新的信号掩码 信号捕捉功能的持续时间(或直到呼叫任何一个 sigprocmask()或sigsuspend()被创建)。这个面具是通过服用形成的 当前信号掩码的联合和sa_mask的值 正在传递的信号,除非是SA_NODEFER或SA_RESETHAND 设置,然后包括正在传递的信号。如果和当用户的时候 信号处理程序正常返回,恢复原始信号掩码。
答案 1 :(得分:0)
信号处理程序可以做很少的事情(它不应该调用,甚至间接调用printf
或malloc
...)许多信号处理程序只需设置一个volatile sigatomic_t
整数变量,稍后在代码中测试。
我建议根据event loop之类的多路复用系统调用来获得一些poll(2)。您可以使用现有的事件循环框架(例如libev,libevent,glib等等)或在poll
之上创建自己的事件循环框架。特定于Linux的timerfd_create(2)& signalfd(2)可以提供很多帮助。