10

system()我用 C 语言编写了一个等待事件的程序,然后按函数运行外部系统命令。

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

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

所以我决定把这个system很重的函数移到另一个程序中,所以我把我的程序改成如下:

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

并编写了另一个程序:

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

但这无济于事,因为如果生产者(第一个程序)的写入速度比消费者(第二个程序)快,那么消费者会丢失一些数据!

有没有办法处理这个问题?

4

3 回答 3

8

您应该将代码返回到它的原始形式——即一个程序调用第二个程序——除了用调用替换system(3)调用popen(3)。现在调用程序可以将事件检查调用与来自外部程序的读取行交错。

Unix 管道机制确保当管道已满时,缓慢的消费者将导致快速的生产者在写入时等待。

您可能还想查看该fileno(3)函数,结合select(2)orpoll(2)以便从外部程序异步读取,以便它永远不会阻塞调用程序。

于 2012-12-28T23:19:58.900 回答
2

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

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

于 2012-12-28T23:19:18.437 回答
2

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

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

我强烈建议在编码之前花几个小时阅读一本好的高级 Linux 编程书籍

于 2012-12-29T08:30:32.377 回答