getutent 和 Linux 定时器问题

发布于 2024-08-03 04:18:58 字数 1403 浏览 2 评论 0原文

我在运行下面的代码时遇到问题,该代码调用 getutent() 来计算当前登录系统的用户总数。计时器将每 1 秒调用一次,并将名为“isSigAlrmOccured”的布尔值设置为 true 并退出。主函数通过检查此布尔值来检查计时器信号是否已发送,并监视登录用户的数量。不幸的是,计时器信号仅正确传送到主程序两次,此后我没有收到任何进一步的信号。在前两个信号之后,暂停函数调用不会被中断。

#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 次

I have a problem running the below code , which invokes getutent() to count the total number of users currently logged in to the system. The timer will be invoked every 1sec and will set the boolean named "isSigAlrmOccured" to true and exit.The main function checks whether the timer signal is delivered by checking this boolen and monitor the number of loggedin users. Unfortunately, the timer signal is delivered to the main program only two times correctly and I don't get any further signals after that. The pause function call doesn't get interrupted after the first two signals.

#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;
}

Output:

Signal Occurred 1 times

Signal Occurred 2 times

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤独岁月 2024-08-10 04:18:58

*utent() 的实现正在使用alarm() 并重置您的闹钟。
你必须做点别的事。

strace ttest(为简洁起见删除了一些行)
[...]
暂停()
--- SIGALRM(闹钟)@ 0 (0) ---
write(1, " 信号出现 1 次\n", 25 信号出现 1 次) = 25
打开(“/ 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;
}

The implementation of *utent() is using alarm() and is reseting your alarm.
You'll have to do something else.

strace ttest ( some lines removed for brevity )
[...]
pause()
--- SIGALRM (Alarm clock) @ 0 (0) ---
write(1, " Signal Occurred 1 times\n", 25 Signal Occurred 1 times) = 25
open("/var/run/utmp", O_RDONLY|O_CLOEXEC) = 3
alarm(0) = 5
rt_sigaction(SIGALRM, {0x7f52580a91c0, [], SA_RESTORER, 0x7f5257fd46e0}, {0x40075c, [ALRM], SA_RESTORER|SA_RESTART, 0x7f5257fd46e0}, 8) = 0
alarm(1) = 0

Example code which only sets the alarm during the sleep period.

#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;
}
攒一口袋星星 2024-08-10 04:18:58

此页面列出了可以从信号处理程序“安全”调用的函数集。如果您调用其他函数,则行为是未定义的。我注意到 setutent() 似乎并不重要,对于初学者来说......

This page lists the set of functions that are "safe" to call from a signal handler. If you call some other function, the behavior is undefined. I notice that setutent() doesn't seem to be on the lest, for starters ...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文