timer_start() 睡眠后的 C 不起作用
Posted
技术标签:
【中文标题】timer_start() 睡眠后的 C 不起作用【英文标题】:C after timer_start() sleep is not working 【发布时间】:2019-01-21 07:24:01 【问题描述】:我在 ubuntu 上使用 eclipse IDE 来编译我的 c 项目。我有一个计时器。启动定时器后,睡眠或睡眠功能不工作。 这是代码;
编辑
/*
============================================================================
Name : TimerTest.c
Author : FK
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include <stdio.h>
#include <stdlib.h> /* , getenv() */
#include <getopt.h>
#include <unistd.h> /* exec(), daemon() */
#include <stdint.h>
#include <string.h> /* memset(), strerror() */
#include <errno.h> /* errno */
#include <libgen.h> /* basename() */
#include <signal.h>
#include <sys/timex.h> /* ntp_gettime() */
#include <time.h>
#include "timer/timer.h"
#define CONFIG_TIMER_INTERVAL 100 /* in ms */
/* global vars decalarations */
static uint8_t _terminate = 0;
static int _signo = 0;
static int init_prg(int argc, char *argv[]);
static void timer_callback(void);
/* function implementations */
static void sig_handler(int signo)
/* http://www.yolinux.com/TUTORIALS/C++Signals.html */
_signo = signo;
switch (signo)
case SIGINT: /* Program interrupt. (ctrl-c) */
_terminate = 1;
break;
case SIGTERM:
_terminate = 1;
break;
/* SIGKILL, SIGSTOP yakalanımıyor! */
default:
break;
int main(int argc, char *argv[])
init_prg(argc, argv);
/* start super loop */
while (1)
printf("test!\n");
//usleep(1000000);
sleep(1);
static int init_prg(int argc, char *argv[])
int res = -1;
if (signal(SIGINT, sig_handler) == SIG_ERR)
//exit(EXIT_FAILURE);
/* Termination, Generated by "kill" command. */
if (signal(SIGTERM, sig_handler) == SIG_ERR)
//exit(EXIT_FAILURE);
start_timer(2000, &timer_callback);
if (res != 0)
//exit(EXIT_FAILURE);
return res;
static void timer_callback(void)
printf("timer works!\n");
执行程序后,它会回显“测试!”迅速。忽略 sleep 或 usleep 命令。如果我注释掉 start_timer 行,它会休眠,在定时器之后它不是。有什么想法吗?
【问题讨论】:
请发布完整的代码示例。现在还不清楚这段代码应该如何表现。 除非我们看到start_timer()
在做什么,否则很难诊断。我怀疑您正在触发SIGALRM
信号。使用setitimer(ITIMER_REAL, ...)
创建的计时器将在到期时生成这样的信号。这足以从sleep()
ing 唤醒线程/程序。
【参考方案1】:
您没有显示用于启动计时器的标准化接口。
不管POSIX specifies,usleep
与
nanosleep()
setitimer()
timer_create()
timer_delete()
timer_getoverrun()
timer_gettime()
timer_settime()
ualarm()
sleep()
未指定。
nanosleep
应该没有这个问题。
来自nanosleep's manpage:
与 sleep(3) 和 usleep(3) 相比,nanosleep() 有以下几点 优点:它为指定睡眠提供了更高的分辨率 间隔; POSIX.1 明确指定它不与 信号;它使恢复睡眠的任务 更容易被信号处理程序中断。
以上建议将您的usleep
替换为:
#include <unistd.h>
int my_usleep(useconds_t Usec);
#include <time.h>
int my_usleep(useconds_t Usec)
return nanosleep(&(const struct timespec)
.tv_sec = Usec/100000, .tv_nsec=1000*Usec%1000000, NULL);
应该解决问题。
【讨论】:
感谢您的回复。我正在对我的代码进行一些测试,我意识到了一些事情。如果定时器间隔值大于超级循环的睡眠值,它正在工作。如果计时器提前进入,它会抑制睡眠或睡眠命令。换句话说,它取消了睡眠。我会更新上面的代码。【参考方案2】:看来您使用的计时器库类似于 https://www.teuniz.net/Timer_code/ 提供的计时器库。如果你在那个库中打开timer.c
,你会看到它使用了setitimer(ITIMER_REAL, ...)
。以这种方式创建的计时器将在计时器到期时生成SIGALRM
。这反过来又会从sleep()
ing 唤醒您的程序。
为什么?因为,如果您阅读 sleep()
的 POSIX 规范(可在 http://pubs.opengroup.org/onlinepubs/009695399/ -> 字母索引 -> sleep()
获得),您将阅读。
sleep() 函数将导致调用线程暂停执行,直到参数 seconds 指定的实时秒数已经过去或将信号传递给调用线程及其action 是调用信号捕获函数或终止进程。
另一方面,如果您不使用上述库,那么您需要准确显示您的start_timer()
函数正在做什么。否则,任何试图帮助你的人都是在黑暗中开枪。
解决方案:线程
我认为您唯一的选择是使用单独的线程 - 一个线程用于休眠的任务,另一个用于处理计时器的任务。
【讨论】:
以上是关于timer_start() 睡眠后的 C 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
iOS startMonitoringForRegion 在睡眠模式下不起作用(黑屏)