【问题标题】:reacting to two signals sent to the CPU in linux在linux中对发送到CPU的两个信号做出反应
【发布时间】:2015-11-22 01:07:13
【问题描述】:

我写了以下代码:

void handler (int signal) {

if (signal==SIGVTALRM) {
    printf("one second passed\n");
}

if (signal==SIGALRM) {
    alarm(1);
    //printf("curret context is %ld\n"  , thread_tbl[currThreadNum].uc.uc_mcontext.cr2);
    currThreadNum=(currThreadNum+1)%THREAD_NUM;
    printf("switching from thread #%d to thread #%d\n", ((currThreadNum-1+THREAD_NUM)%THREAD_NUM), currThreadNum);
    printf("current thread number is %d\n", currThreadNum);
    thread_tbl[(currThreadNum-1+THREAD_NUM)%THREAD_NUM].vtime=+1000;
    swapcontext( &(thread_tbl[ (currThreadNum-1+THREAD_NUM)%THREAD_NUM ].uc), &(thread_tbl[currThreadNum ].uc) );
}

}

int ut_start(void) {

int i=0;
struct sigaction sa;
struct itimerval itv;

// set the signal
sa.sa_flags=SA_RESTART;
sigfillset(&sa.sa_mask);
sa.sa_handler = handler;

itv.it_interval.tv_sec=0;
itv.it_interval.tv_usec=100;
itv.it_value=itv.it_interval;

if (sigaction(SIGALRM, &sa, NULL)<0) {
    abort();
}

if (sigaction(SIGVTALRM, &sa, NULL)<0) {
    abort();
}

setitimer(ITIMER_VIRTUAL, &itv, NULL);

for(i=0; i<TAB_SIZE; i++) {
    getcontext(&thread_tbl[i].uc);   // get the context the content of current thread
    makecontext(&thread_tbl[i].uc, (void(*)(void))func ,1, i); // when this context is activated, func will be executed and then uc.uc_link will get control
}

//start running
alarm(1);
currThreadNum=0;
//printf("currThreadNum=0\n");
swapcontext(&temp_context, &thread_tbl[0].uc);

}

我的目的是编写一个同时响应 SIGVTALRM 信号和 SIGALRM 的程序。但是,当我运行该程序时,该程序似乎只对 SIGALRM 信号作出反应。

在函数 ut_start() 中,我启动了一个每 100 微秒重置一次的计时器。我没有看到任何证据表明它有效。

还有一件事,如何调试这个程序以便我可以真正看到计时器已经启动?在调试模式下是否有任何变量可以告诉我有关计时器状态的信息?

【问题讨论】:

  • 您对setitimer 的调用成功了吗?您的程序使用 CPU 是否足以触发 ITIMER_VIRTUAL 到期?
  • 我想我有个主意。我看到,一旦我删除最后一行“swapcontext”并写(而不是)“while(1);”,它就会按预期工作。你知道为什么 swapcontext 会禁用计时器吗?

标签: linux timer signals setitimer sigaction


【解决方案1】:

我想我自己找到了答案。

我提供的功能只是我的程序的一部分。在程序的某个地方,我使用了函数 sleep()。

根据睡眠的文档(http://linux.die.net/man/3/sleep):

sleep() 可以使用 SIGALRM 实现;混合对警报(2)的调用和 sleep() 是一个坏主意。使用信号处理程序中的 longjmp(3) 或 在睡眠时修改 SIGALRM 的处理将导致未定义 结果。

当我删除 sleep() 函数时,一切正常。

【讨论】:

    猜你喜欢
    • 2017-08-19
    • 2022-12-03
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    • 2022-10-21
    • 1970-01-01
    相关资源
    最近更新 更多