2012-12-28 26 views
10

我在C中编写了一个等待事件的程序,然后通过system()函数运行外部系统命令。C中的快速生产者/慢速消费者

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

我对此有seriuos问题,cmd是一个沉重的命令,并需要几秒钟才能完成,我的应用程序错过这一时间框架的一些事件。

所以我决定移动system功能,这是非常沉重的,到另一个程序,所以我改变了我的程序如下:

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

并写了另一个程序:

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

但它并没有帮助,因为如果生产者(第一个程序)比消费者(第二个程序)写得更快,那么消费者会遗漏一些数据!

有什么办法可以解决这个问题吗?

+4

使用线程捕获事件,将它们添加到队列中,并让您的消费者从该队列中拉出。 – Falmarri

+0

是否可以使用多个线程来减轻消费者的负担,同时让生产者单线程?当然,这是一场失败的战斗,但根据你的要求,它可能足以救你。如果额外线程仍然过多,您还应该查看数据存储。 – pickypg

+0

你如何设置你的管道?当然,如果您持续获得的数据超过您的处理数量,那么某些内容将“给予”。但是完全有可能使用管道来缓慢处理大量数据。否则,它将无法执行'cat myprog.c | gcc -o myprog' - 它确实 - gcc有时非常慢,cat会尽可能快地将它推送到管道。 –

回答

8

你应该代码恢复到原来的形态—就是一个单独的程序调用第二程序—除了更换system(3)呼叫与电话popen(3)。现在调用程序可以将事件检查的调用与来自外部程序的读取行交错。

Unix管道机制确保缓慢的使用者将导致快速生产者在管道满时写入时等待。

你也可能想看看进入fileno(3)功能,具有select(2)poll(2)为了使从外部程序异步阅读结合起来,使之能从未阻止调用程序。

+0

感谢您的及时响应。我不熟悉linux下的C编程,请给出示例代码。谢谢 – Maryam

+0

哇!它就像一个魅力!谢谢 – Maryam

+0

你真的应该得到这个主题的书籍之一。一块一块地学习它有其重点,但是有一个你需要接受的格式,只有当你在短时间内学到很多东西时才会发生。我推荐* W. Richard Stevens在Unix环境下的高级编程* 2/e。还有其他这样的书。在本书的年龄不要被关闭。即使是第一版对于现代Linux编程仍然有95%的用处。内核API和C标准库在那个时候并没有改变那么多。 –

2

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

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

+0

不,事件有一些重要的数据,它们应该被处理并存储在其他地方。 – Maryam