如何在Linux下加速连续程序启动?

时间:2011-12-08 17:54:03

标签: c linux bash startup

我用C编写了两个相对较小的程序。它们都使用文本数据相互通信。程序A从给定的输入产生一些问题,B评估它们并为A的另一次迭代创建输入。

这是我目前使用的bash脚本:

for i in {1..1000}
do 
  ./A data > data2;
  ./B data2 > data;
done

问题在于,由于A和B所做的事情并不是非常耗时,因此大部分时间都花在(正如我想的)启动应用程序上。当我测量脚本运行的时间时,我得到:

$ time ./bash.sh
real    0m10.304s
user    0m4.010s
sys     0m0.113s

所以我的主要问题是:有没有办法更快地传达这两个应用程序的数据?我不想将它们集成到一个应用程序中,因为我正在尝试构建一个具有独立,易于通信的工具的工具集(正如“Unix编程的艺术”中所建议的那样,我正在学习编写可重用的方法软件)。

PS。 data和data2文件包含那些应用程序一次性整体所需的数据集(因此,例如,通过一段时间的数据进行通信是不可能的)。

感谢您的任何建议。

欢呼声,

kajman

5 个答案:

答案 0 :(得分:3)

你能创建named pipe吗?

mkfifo data1
mkfifo data2
./A data1 > data2 &
./B data2 > data1

如果您的应用程序正在循环读写,这可能有效:)

答案 1 :(得分:1)

如果使用管道将程序A的stdout传输到程序B的stdin,则无需在每个循环中写入“data2”文件。

./A data1 | ./B > data1

程序B需要具有使用stdin输入而不是指定文件的能力。

答案 2 :(得分:1)

如果您想让程序运行得更快,您需要了解使程序运行缓慢的原因。专门用于测量正在运行的程序的性能的计算机科学领域称为profiling

一旦发现程序的哪个内部部分运行缓慢,通常可以加快速度。你如何加速这个项目在很大程度上取决于“缓慢的部分”正在做什么以及它是如何“完成”。

有些人推荐使用管道将数据直接从一个程序的输出移动到另一个程序的输入中。假设您重写了以管道方式处理输入和输出的工具,可能会提高性能。同样,它取决于你正在做什么以及你正在做什么

例如,如果你的工具只是将windows样式的行尾修改为unix样式的行尾,那么程序可能会读取一行,等待它可用,检查行尾和写出具有所需行尾的行。或者工具可能读入所有数据,在内存中每个“错误”的行尾进行替换调用,然后写出所有数据。使用第一种解决方案,管道加快了速度。使用第二种解决方案,管道不会加快任何速度。

原因是真的很难回答这样的问题是因为您需要的修复真的取决于您拥有的代码,您要解决的问题以及您的方法正在解决它。最后,并不总是100%保证代码可以加速;然而,几乎每一段代码都有机会加速。使用分析来加速缓慢的部分,而不是浪费你的时间来处理程序中只调用一次的部分,并且代表程序运行时的0.001%。

请记住,如果你将程序运行时的0.001%加速到50%,你实际上只加快了整个程序0.0005%。使用分析来确定占用运行时间90%并专注于它的代码块。

答案 3 :(得分:0)

我不得不想知道为什么,如果A和B依赖于彼此运行,你是否希望它们成为独立工具集的一部分。

一种解决方案是在两者之间达成妥协:

  1. 创建一个包含A。
  2. 的库
  3. 创建一个包含B。
  4. 的库
  5. 创建一个产生两个线程的程序,1个包含A,2个包含B。
  6. 创建一个告诉A运行的信号量和另一个告诉B运行的信号量。
  7. 在调用A in 1的函数之后,递增B的信号量。
  8. 在2中调用B的函数之后,递增A的信号量。
  9. 另一种可能性是在程序中使用文件锁定:

    1. 使A和B都以无限循环执行(或者无论多少次处理数据)
    2. 添加代码以尝试在A和B的无限循环开始时锁定两个文件(如果没有,请再次尝试,以便在锁定之前不要执行任何操作)。
    3. 在每个循环结束时添加代码以解锁并睡眠超过步骤2中的睡眠时间。
    4. 其中任何一个都解决了在运行之间启动程序的开销问题。

答案 4 :(得分:0)

几乎可以肯定,应用程序启动不是瓶颈。 Linux将最终缓存大部分程序,这意味着启动将逐步更快(到某一点)启动程序的次数越多。

你需要到别处寻找你的瓶颈。