对发送到 linux 中的 CPU 的两个信号做出反应
reacting to two signals sent to the CPU in linux
我写了下面的代码:
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 微秒重置一次的计时器。我没有看到任何证据表明它有效。
还有一件事,如何调试这个程序才能真正看到计时器已经启动?在调试模式下是否有任何变量可以告诉我有关计时器状态的信息?
我想我自己找到了答案。
我提供的功能只是我程序的一部分。在程序的某处,我使用了函数 sleep()。
根据 sleep (http://linux.die.net/man/3/sleep) 的文档:
sleep() may be implemented using SIGALRM; mixing calls to alarm(2) and
sleep() is a bad idea.Using longjmp(3) from a signal handler or
modifying the handling of SIGALRM while sleeping will cause undefined
results.
当我删除 sleep() 函数时,一切正常。
我写了下面的代码:
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 微秒重置一次的计时器。我没有看到任何证据表明它有效。
还有一件事,如何调试这个程序才能真正看到计时器已经启动?在调试模式下是否有任何变量可以告诉我有关计时器状态的信息?
我想我自己找到了答案。
我提供的功能只是我程序的一部分。在程序的某处,我使用了函数 sleep()。
根据 sleep (http://linux.die.net/man/3/sleep) 的文档:
sleep() may be implemented using SIGALRM; mixing calls to alarm(2) and sleep() is a bad idea.Using longjmp(3) from a signal handler or modifying the handling of SIGALRM while sleeping will cause undefined results.
当我删除 sleep() 函数时,一切正常。