Linux下如何在C中实现计时器的回调函数 [英] how to implement timer's callback function in C under Linux

查看:411
本文介绍了Linux下如何在C中实现计时器的回调函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have searched the possible solution on many forums for several days but have no luck; ( I post my question here and your reply is greatly appreciated.

想法: 使用脚本控制灯光(在Linux下为C)

IDEA: Use a script to control lights (in C under Linux)

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

APPLICATION SCENARIO I have three lights: red, blue and green. The script has the schedules to control them. For example, From now in 10 seconds, turn on the red light for 2 seconds; From now in 15 seconds, turn on the blue light for 10 seconds; From now in 21 seconds, turn on the red light for 5 seconds; From now in 5 seconds, turn on the green light for 7 seconds; From now in 103 seconds, turn on the green light for 11 seconds; ….. When and how long to turn on the light are totally arbitrary. And this program should be able to expand to hundred lights and thousands schedules.

如何对其进行编码 我的想法是有两个进程和一个邮箱: 第一个过程读取脚本文件,并将调度表解析为许多计时器.计时器到期后,它将向邮箱发送一条消息(包括指示灯ID和操作– ON或OFF –). 第二个过程是根据邮箱中的消息打开或关闭指定的指示灯.

HOW TO CODE IT My idea is to have two processes and one mailbox : The first process reads the script file and parse the schedules into many timers. Once the timer expires, it send a message (including light ID and action – ON or OFF --) to the mailbox. The second process is to turn on or off the specified light based on the message from the mailbox.

每个时间表都将解析为两个计时器: 时间表:从现在起10秒钟内,打开红灯2秒钟; 解析为: 计时器1:计时器将在10秒后过期;一旦过期,它将灯ID(红灯)和操作(ON)作为消息传递到邮箱; 计时器2:计时器将在(10 + 2)秒后过期;一旦过期,它将灯ID(红灯)和操作(关闭)作为消息传递到邮箱;

Each schedule will be parsed into two timers: Schedule: From now in 10 seconds, turn on the red light for 2 seconds; Parsed to: Timer 1: timer will expire in 10 seconds; once expire, it passes the light ID (red light) and action (ON) as a message to the mailbox; Timer 2: timer will expire in (10+2) seconds; once expire, it passes the light ID (red light) and action (OFF) as a message to the mailbox;

第二个过程不断检查邮箱,并根据收到的消息在适当的灯光下采取适当的措施.

The second process continually checks the mailbox and takes the proper action on proper light based on the received message.

我的问题 Linux()中的计时器一旦过期就只发出相同的SIGALRM信号.我无法将灯光ID和操作传递到邮箱.我还有其他方法吗?非常感谢.

MY QUESTION The timer in Linux () only issues the same SIGALRM signal once expired. It’s not possible for me to pass the light ID and action to the mailbox. Do I have any other way to do it? Thanks a lot.

推荐答案

Tonttu的解决方案非常好.

Tonttu's solution is pretty good.

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

Use a queue implemented with a linked list:

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排序). 接下来,您的主循环应如下所示:

Parse your file and fill the queue (keep it sorted by t). Next, your main loop should look like this:

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).

As usual, read the fine manual. You'll need time(2). If you need sub-second time, use gettimeodday(2).

这篇关于Linux下如何在C中实现计时器的回调函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆