Linux下如何在C中实现计时器的回调函数 [英] how to implement timer's callback function in C under Linux
问题描述
我已经在许多论坛上搜索了可能的解决方案几天,但是没有运气; (我在这里发布我的问题,非常感谢您的答复.
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屋!