C 除了睡眠,还有信号灯

C 除了睡眠,还有信号灯,c,sleep,C,Sleep,我有一个简单的c程序(在linux上)。程序中的步骤如下所示: 在while循环中,它调用一个只返回一条记录的查询。它本质上是一个视图,它查找一个名为“processed”的列,该列的值为“0”,并使用“limit 1” 我读取结果集中的记录并执行一些计算,然后将结果上传回数据库。我还将processed列设置为“1” 如果这个查询没有返回任何记录,我将退出while循环 一旦退出while循环,程序就会退出 一旦它完成运行,我不希望程序退出。原因是数据库可能在未来30分钟内获得更多符合条件的记

我有一个简单的c程序(在linux上)。程序中的步骤如下所示:

  • 在while循环中,它调用一个只返回一条记录的查询。它本质上是一个视图,它查找一个名为“processed”的列,该列的值为“0”,并使用“limit 1”

  • 我读取结果集中的记录并执行一些计算,然后将结果上传回数据库。我还将processed列设置为“1”

  • 如果这个查询没有返回任何记录,我将退出while循环

  • 一旦退出while循环,程序就会退出

  • 一旦它完成运行,我不希望程序退出。原因是数据库可能在未来30分钟内获得更多符合条件的记录。我希望这个程序是长时间运行的程序,可以检查任何新记录并再次启动while循环来处理这些记录

    我不做任何多线程或花哨的东西。我在谷歌上搜索了一些关于信号量的帖子


    走这条路对吗?有没有简单的信号量示例和解释?

    首先,我希望您使用的是事务。否则,1和2之间可能存在竞争条件

    我认为您的问题是“当SQL表中有更多信息需要处理时,您的程序如何知道?”有几种方法可以做到这一点

    最简单的是。你的程序只是偶尔检查一下是否有工作。如果没有,它会睡一会儿。如果检查很便宜,或者你不需要经常检查,那么轮询就可以了。它非常健壮,工人和供应商之间不需要协调。工人只是检查工作

    另一种方法是将程序块置于某种I/O上,比如等待文件锁定。这就是信号量的含义。事情是这样的

  • 队列是空的
  • 生产者获得信号量文件的独占锁
  • 您的工作人员试图锁定信号量文件,它会阻止
  • 生产者添加到队列并释放其锁
  • 工人立即解除了封锁。
  • 检查队列
  • 做它的工作
  • …但重置系统是一个问题。在没有轮询的情况下,生产者不知道队列何时再次为空。这需要添加到SQL表中的所有内容都知道这个过程,并且都位于同一台机器上。即使你让它工作,它也很容易受到死锁和比赛条件的影响

    另一种方法是通过信号。生产者进程向工作者进程发送一个信号,表示“我添加了一些工作”。如上所述,这需要在添加到SQL表的内容和工作程序之间进行协调

    更好的解决方案是不对工作队列使用SQL。这本来就是你必须调查的事情。而是使用命名管道或网络管道。管道自动充当队列。生产者在添加工作时向管道写入数据。工人连接到管道并从中读取数据以获得更多工作。如果没有工作,它会悄悄地阻止等待工作。管道可以包含执行工作所需的所有信息,也可以只包含其他位置有工作的指示(如行的ID)


    最后,根据需要执行的处理量,您可以尝试在由表更新触发的存储过程中执行所有处理。

    信号量用于多线程同步。我想不出它们在这里有什么用处。这是“生产者/消费者问题”的一个例子。信号量(和其他同步原语)只有在您能够改变生产者(外部进程)和消费者(程序)以使用它们时才适用。在单线程应用程序中,或者在生产者没有(或不能)使用系统级IPC的情况下,它们对您没有帮助。考虑使用系统计时器来释放内核,使用睡眠是可以接受的。我不确定你在问什么。您不希望程序退出,因此不要在循环结束时退出。我认为你真正的问题是“我如何最好地让我的程序等待,直到有更多的东西要处理?”@Schwern:“我如何最好地让我的程序等待,直到有更多的东西要处理?”-这是正确的。我认为睡眠不是等待的正确方式。在这种情况下,有没有正确的等待方式?谢谢。我想说的是,使用sleep并没有什么错,而且每隔一段时间就对数据库进行一次轮询。代价是您的响应速度不够快,一旦数据库发生变化,可能会占用整个睡眠时间,直到您的消费者开始处理数据。在这个特定的示例中,您不需要记录它的事务,因为它不是多线程的,因此不存在争用条件。@AndreasLundgren在您读取、处理数据的任何时候,然后在SQL中进行更新可能会导致数据损坏。另一个进程可以连接到SQL数据库,并开始对正在处理的同一行执行操作。这是基本的SQL数据完整性。你不相信你是唯一的过程;也许你现在是,但谁知道以后会发生什么?您使用事务处理。谢谢大家。我需要仔细阅读这里概述的各种策略。