getutent和Linux计时器问题

raj*_*han 2 c linux posix system-calls

我在运行以下代码时遇到问题,该代码调用getutent()来计算当前登录到系统的用户总数.计时器将被调用每1秒,将设置名为"isSigAlrmOccured",以真实,exit.The主要功能检查定时器信号是否通过检查该boolen交付和监控的loggedIn用户数量的布尔值.不幸的是,定时器信号仅正确地传送到主程序两次,之后我没有得到任何进一步的信号.在前两个信号之后,暂停函数调用不会被中断.

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

信号发生1次

信号发生2次

cod*_*eDr 7

*utent()的实现是使用alarm()并重置您的警报.
你必须做点别的事情.

strace的t检验(一些线为简洁移除)
[...]
暂停()
--- SIGALRM(闹钟)@ 0(0)---
写(1, "信号发生过1次的\n",25信号发生1倍)= 25
打开( "/变种/运行/ 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;
}
Run Code Online (Sandbox Code Playgroud)