我已经在许多论坛上搜索了几天的可能的解决方案,但没有运气;(我在这里发布了我的问题,非常感谢您的回复。
想法:使用脚本控制灯光(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传递到邮箱。我有没有别的办法呢?非常感谢。
发布于 2011-01-19 23:08:37
SIGALRM不是一种非常可靠的方式来实现这样的事情,你不能同时有多个警报请求。这两个进程设计是否意味着类似于at(1)/atd(8)?不幸的是,"at“在这里并不是很精确,我甚至不确定当你安排一些事情时,它是否会使用秒。
然而,只用一个程序就可以很容易地解决这个问题。只需将任务拆分成像“打开/关闭X灯”这样的事件,将它们放到有序队列中,并有一个循环读取队列并休眠,直到行动的时间。
发布于 2011-01-20 00:37:00
Tonttu的解决方案非常好。
使用使用链表实现的队列:
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排序)。接下来,您的主循环应该如下所示:
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)。
https://stackoverflow.com/questions/4736143
复制相似问题