C中的快速生产者/缓慢消费者

时间:2012-12-28 23:15:04

标签: c++ c linux unix

我在C中编写了一个等待事件的程序,然后通过system()函数运行外部系统命令。

while( true ){
    wait_for_event();
    system("cmd");
}

我有一个严重的问题,cmd是一个繁重的命令,需要几秒钟才能完成,我的应用程序错过了这段时间内的一些事件。

所以我决定将system函数(非常重)移到另一个程序中,所以我改变了我的程序如下:

while( true ){
    wait_for_event();
    write_to_fifo("cmd");
}

并写了另一个程序:

while(true){
    system(read_from_pipe());
}

但它没有帮助,因为如果生产者(第一个程序)的写入速度比消费者(第二个程序)快,那么消费者会错过一些数据!

有没有办法解决这个问题?

3 个答案:

答案 0 :(得分:8)

您应该将代码恢复为原始格式 - 即,调用第二个程序的单个程序 - 除了您使用system(3)调用替换popen(3)调用。现在,调用程序可以将事件检查的调用与来自外部程序的读取行交错。

Unix管道机制确保缓慢的消费者会在管道充满时写入快速生产者等待。

您可能还想查看fileno(3)函数,结合select(2)poll(2),以便从外部程序中异步读取,以便它可以从不阻止调用程序。

答案 1 :(得分:2)

如果你需要的只是事件的数量,你可以拥有一个全局计数器。为避免竞争条件,您可能需要使用信号量。当然你需要有两个线程。

由于您的事件包含重要信息,因此可以使用列表(或具有足够数量的插槽的数组)来存储传入数据。您可以使用互斥锁来保护此列表。

答案 2 :(得分:2)

您可以使用fork(2)execve(2)waitpid(2)以及pipe(2)dup2(2)和其他系统调用显式启动外部程序。

您可能需要一个事件循环。您可以使用poll(2)系统调用(或者像libev这样的事件循环库,它使用poll)。

我强烈建议您在编码前花几个小时阅读好advanced linux programming book