getutent 和 Linux 定时器问题
我在运行下面的代码时遇到问题,该代码调用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
*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
仅在睡眠期间设置闹钟的示例代码。
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.
此页面列出了可以从信号处理程序“安全”调用的函数集。如果您调用其他函数,则行为是未定义的。我注意到
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 ...