首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Linux下用C语言实现定时器回调函数

如何在Linux下用C语言实现定时器回调函数
EN

Stack Overflow用户
提问于 2011-01-19 22:07:54
回答 2查看 6.6K关注 0票数 4

我已经在许多论坛上搜索了几天的可能的解决方案,但没有运气;(我在这里发布了我的问题,非常感谢您的回复。

想法:使用脚本控制灯光(Linux下的C语言)

应用场景我有三个灯:红色,蓝色和绿色。该脚本具有控制它们的计划。例如,从现在开始10秒,打开红灯2秒;从现在开始15秒,打开蓝灯10秒;从现在开始21秒,打开红灯5秒;从现在开始5秒,打开绿灯7秒;从现在开始103秒,打开绿灯11秒;…。。开灯的时间和时间完全是随意的。这个程序应该能够扩展到数百个灯光和数千个时间表。

我的想法是有两个进程和一个邮箱:第一个进程读取脚本文件,并将计划解析为多个计时器。一旦计时器超时,它就会向邮箱发送一条消息(包括灯光ID和动作-开或关)。第二个过程是根据来自邮箱的消息打开或关闭指定的灯。

每个时间表将解析为两个定时器: Schedule:从现在起10秒后,打开红灯2秒;解析为: timer 1:定时器将在10秒后到期;一旦到期,它将把灯ID (红灯)和动作( on )作为消息传递到邮箱;定时器2:定时器将在(10+2)秒内到期;一旦过期,它将灯ID (红灯)和动作(OFF)作为消息传递到邮箱;

第二个过程不断地检查邮箱,并基于接收到的消息对适当的光采取适当的行动。

我的问题是,Linux ()中的计时器只在到期后才发出相同的SIGALRM信号。我不可能将light ID和action传递到邮箱。我有没有别的办法呢?非常感谢。

EN

回答 2

Stack Overflow用户

发布于 2011-01-19 23:08:37

SIGALRM不是一种非常可靠的方式来实现这样的事情,你不能同时有多个警报请求。这两个进程设计是否意味着类似于at(1)/atd(8)?不幸的是,"at“在这里并不是很精确,我甚至不确定当你安排一些事情时,它是否会使用秒。

然而,只用一个程序就可以很容易地解决这个问题。只需将任务拆分成像“打开/关闭X灯”这样的事件,将它们放到有序队列中,并有一个循环读取队列并休眠,直到行动的时间。

票数 3
EN

Stack Overflow用户

发布于 2011-01-20 00:37:00

Tonttu的解决方案非常好。

使用使用链表实现的队列:

代码语言:javascript
复制
struct node {
    struct node *next;
    time_t t;        // time to start
    int action;   // on / off
    int lamp_id;
};

struct queue {
    struct node *head;
    struct node *tail;
};

解析您的文件并填充队列(保持按t排序)。接下来,您的主循环应该如下所示:

代码语言:javascript
复制
time_t start = time(NULL);
while(!queue_empty()) {
    time_t now = time(NULL) - start;
    struct node *n = queue.head;        

    if(n->t <= now) {
        lamp(n->lamp_id, n->action); // set the status of a lamp
        queue_next();
    } else {
        sleep(n->t - now);
    }
}

像往常一样,请阅读详细的手册。您将需要time(2)。如果您需要亚秒级的时间,请使用gettimeodday(2)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4736143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档