我在运行以下代码时遇到问题,该代码调用getutent()来计算当前登录到系统的用户总数。定时器将每1秒调用一次,并将名为“isSigAlrmOccured”的布尔值设置为true并退出。主函数通过检查此boolen来检查定时器信号是否已发送并监视登录用户的数量。不幸的是,定时器信号仅正确地传送到主程序两次,之后我没有得到任何进一步的信号。在前两个信号之后,暂停函数调用不会被中断。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <utmp.h>
#include <errno.h>
static int isSigAlrmOccured;
void alarm_handler (int signo)
{
static int i=1;
printf("\n Signal Occurred %d times\n",i++);
isSigAlrmOccured = 1;
}
int main (int argc, char *argv[]) {
struct itimerval delay;
struct utmp *utmpstruct;
int numuser;
int ret;
signal (SIGALRM, alarm_handler);
delay.it_value.tv_sec = 1;
delay.it_value.tv_usec = 0;
delay.it_interval.tv_sec = 1;
delay.it_interval.tv_usec = 0;
ret = setitimer (ITIMER_REAL, &delay, NULL);
if (ret) {
perror ("setitimer");
return 0;
}
for (;;) {
pause ( );
/* count the number of users */
if ( (errno == EINTR) && (isSigAlrmOccured) ) {
isSigAlrmOccured = 0;
setutent();
while ((utmpstruct = getutent())) {
if ((utmpstruct->ut_type == USER_PROCESS) &&
(utmpstruct->ut_name[0] != '\0'))
numuser++;
}
endutent();
}
}
return 0;
}
输出:
信号发生1次
信号发生2次
答案 0 :(得分:7)
* utent()的实现是使用alarm()并重置警报 你必须做点别的事情。
strace ttest(为简洁起见删除了一些行)
[...]
暂停()
--- SIGALRM(闹钟)@ 0(0)---
写(1,“信号发生1次\ n”,25信号发生1次)= 25
open(“/ var / run / utmp”,O_RDONLY | O_CLOEXEC)= 3
报警(0)= 5
rt_sigaction(SIGALRM,{0x7f52580a91c0,[],SA_RESTORER,0x7f5257fd46e0},{0x40075c,[ALRM],SA_RESTORER | SA_RESTART,0x7f5257fd46e0},8)= 0
alarm(1)= 0
仅在睡眠期间设置闹钟的示例代码。
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <utmp.h>
#include <errno.h>
static int isSigAlrmOccured;
void alarm_handler (int signo)
{
static int i=1;
printf("\n Signal Occurred %d times\n",i++);
isSigAlrmOccured = 1;
}
int main (int argc, char *argv[]) {
struct itimerval delay;
struct utmp *utmpstruct;
int numuser;
int ret;
for (;;) {
signal (SIGALRM, alarm_handler);
alarm(1); /* wake me later */
pause ( );
/* count the number of users */
if ( (errno == EINTR) && (isSigAlrmOccured) ) {
signal (SIGALRM, SIG_DFL);
isSigAlrmOccured = 0;
numuser = 0;
setutent();
while ((utmpstruct = getutent())) {
if ((utmpstruct->ut_type == USER_PROCESS) &&
(utmpstruct->ut_name[0] != '\0'))
numuser++;
}
endutent();
printf("found %d users\n", numuser);
}
}
return 0;
}
答案 1 :(得分:1)
This page列出了从信号处理程序调用“安全”的函数集。如果调用其他函数,则行为未定义。我注意到setutent()
似乎并不是最开始的......