在 Ksh 和 Perl 中并行执行任务的最佳方式是什么?

发布于 2024-07-07 22:42:22 字数 337 浏览 8 评论 0原文

我有一个大型 C++ 项目,需要在没有并行 make 的平台上构建(例如 Linux 上的 make -j)。 服务器有 6 个 CPU,我想手动进行并行构建。

我可以为大约 300 个目标文件生成这样的任务列表。 我使用 Makefile 进行依赖性检查和增量构建:

make -f Makefile obj1.o

make -f Makefile obj2.o

make -f Makefile obj3.o ...

我如何使用 Ksh 和 Perl 并行执行这些任务,同时运行的任务不超过 6 个? (Java 或 Python 不可用:-( )

I have this large C++ project that I need to build on a platform that does not have a parallel make (like make -j on Linux). The server has 6 CPU's and I want to do a parallel build manually.

I can generate a task list like this for about 300 object files. I use the Makefile for the dependency checks and incremental build:

make -f Makefile obj1.o

make -f Makefile obj2.o

make -f Makefile obj3.o
...

How would I execute these tasks in parallel with no more then 6 tasks running at a time using Ksh and Perl? (Java or Python are not available :-( )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

街道布景 2024-07-14 22:42:22

在 Perl 中,您应该查看 Parallel::ForkManager。 你可以这样做:

my @make_obj = qw(
  obj1.o
  obj2.o
  obj3.o
  ...
);

my $fm = $pm = new Parallel::ForkManager(6);
foreach my $obj (@make_obj) {
  $fm->start and next;
  system("make -f Makefile $make_obj");
  $fm->finish();
}

In Perl the you should look at Parallel::ForkManager. You could do something like this:

my @make_obj = qw(
  obj1.o
  obj2.o
  obj3.o
  ...
);

my $fm = $pm = new Parallel::ForkManager(6);
foreach my $obj (@make_obj) {
  $fm->start and next;
  system("make -f Makefile $make_obj");
  $fm->finish();
}
万劫不复 2024-07-14 22:42:22

分叉的另一种方法是在自己的线程中运行每个 make。

use threads;

my $max_threads = 5;

my @targets = qw(obj1.o obj2.o obj3.o ...);
while(@targets) {
    my $num_threads = threads->list(threads::running);
    if( $num_threads < $max_threads ) {
        my $target = shift @targets;
        threads->create(sub { return system "make $target" });
    }
}

不幸的是,我的手在两位左右挥舞。 首先是让循环静态等待,直到线程完成。 我相信这是使用threads::shared 的 cond_wait() 和信号量变量来完成的。

第二个是从 make 获取返回值,这样您就可以知道是否出现故障并停止构建。 为此,您必须 join() 每个线程才能获取 system() 的结果,即进程的退出代码。

抱歉仓促回复。 希望社区能够填补剩下的部分。

An alternative to forking is to run each make in its own thread.

use threads;

my $max_threads = 5;

my @targets = qw(obj1.o obj2.o obj3.o ...);
while(@targets) {
    my $num_threads = threads->list(threads::running);
    if( $num_threads < $max_threads ) {
        my $target = shift @targets;
        threads->create(sub { return system "make $target" });
    }
}

I am unfortunately hand waving around two bits. First is making the loop wait quiescently until a thread finishes. I believe this is accomplished using threads::shared's cond_wait() and a semaphore variable.

The second is getting the return value from make, so you know if something failed and to halt the build. To do that you'd have to join() each thread to get the result of system(), the process' exit code.

Sorry for the hasty reply. Hopefully the community will fill in the rest.

想挽留 2024-07-14 22:42:22

HPUX 上的 gnu make 没有 -j 标志吗?

http://hpux.connect.org.uk/hppd/hpux /Gnu/make-3.81/

Does gnu make on HPUX not have the -j flag?

http://hpux.connect.org.uk/hppd/hpux/Gnu/make-3.81/

梦旅人picnic 2024-07-14 22:42:22

使用 GNU Parallel 您可以编写:

parallel -j6 make -f Makefile obj{}.o ::: {1..500}

10 秒安装:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

了解更多: http://www.gnu .org/software/parallel/parallel_tutorial.html https://www.youtube.com /playlist?list=PL284C9FF2488BC6D1

Using GNU Parallel you can write:

parallel -j6 make -f Makefile obj{}.o ::: {1..500}

10 second installation:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

Learn more: http://www.gnu.org/software/parallel/parallel_tutorial.html https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

终陌 2024-07-14 22:42:22

如果操作系统正确处理处理器间通信和调度,那么只要不存在相互依赖关系,您就应该能够将所有进程放入后台进程中。

如果它们都是独立的,我会发出一系列如下命令:

make -f Makefile obj1.o &
make -f Makefile obj2.o &
...
make -f Makefile objn.o &

对于依赖项,用双与号 (&&) 将它们串起来,以便依赖项不会启动,直到它的《父母》已经完结了。

我意识到这并不完全是您要求的解决方案,但这就是我解决问题的方式:)

If the OS is properly handling inter-processor communication and scheduling, you should just be able to throw all the makes into backgrounded processes, as long as there are no interdependencies.

If they're all independent, I would issues a series of commands like this:

make -f Makefile obj1.o &
make -f Makefile obj2.o &
...
make -f Makefile objn.o &

With dependencies, string them with the double ampersand (&&) so that the dependent item doesn't start until its 'parent' has finished.

I realize that's not quite the solution you requested, but it's how I would attack the problem :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文