3

如果我创建一个简单的规则,例如

rule '.o' => ['.c'] do |t|
  sh "cc #{t.source} -c -o #{t.name}"
end

如何告诉 Rake 我希望自动生成的任务可以并行化?

4

3 回答 3

5

正如 Dennis Rake 所说,规则被实现为任务

因此,将任务转换为多任务的 -m 标志也将规则转换为“多规则”

require 'rake/clean'

rule '.ext2' => '.ext1' do |t|
    sh "cp #{t.source} #{t.name}"
    sleep(1)
end

def dependencies(input_file)
    base, is, ext = input_file.split('.')
    _from, _to = is.split('-')
    files = []
    Integer(_from).upto(Integer(_to)) do |i|
        files << "#{base}_#{i}.#{ext}"
    end
    return files
end

rule ".ext2" => lambda { |i| dependencies(i) } do |t|
    sh "touch #{t.source}"
end

task :make_files do |t|
    1.upto(20) do |i| 
        sh "touch file_#{i}.ext1"
    end
end

CLEAN = FileList['*.ext2']

运行以下命令(非线程):

rake make_files
time rake file.1-20.ext2

我明白了

real    0m20.232s
user    0m0.134s
sys     0m0.082s

有 5 个线程:

rake clean
time rake -m -j 5 file.1-20.ext2

我明白了

real    0m4.152s
user    0m0.122s
sys     0m0.071s

有 20 个线程:

rake clean
time rake -m -j 20 file.1-20.ext2

我明白了

real    0m1.167s
user    0m0.130s
sys     0m0.065s

我使用 sleep(1) 来模拟“work/io”,如果你的进程阻塞很多或者你有很多内核,这可能对你有用:)

编辑:正如Shadow 在评论中指出的那样,以下将“多任务”切换为始终开启

Rake.application.options.always_multitask = true
于 2014-03-19T08:48:52.697 回答
1

这个问题不是很清楚,但不是您要寻找的 Rake::MultiTask 吗?

http://rake.rubyforge.org/Rake/MultiTask.html

我自己从未使用过它,但文档建议:

multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do
  puts "All Copies Complete"
end

http://rake.rubyforge.org/files/doc/rakefile_rdoc.html

DSL 中的定义rulelib/rake/dsl_definitions.rb(在 Rake 10.1.1 中):

# Declare a rule for auto-tasks.
#
# Example:
#  rule '.o' => '.c' do |t|
#    sh %{cc -o #{t.name} #{t.source}}
#  end
#
def rule(*args, &block)
  Rake::Task.create_rule(*args, &block)
end

rule但是,粗略地扫描当前代码不会产生DSL中构造的内置内容。如果有帮助,请在代码中搜索类似的内容@rulesrules.生成一个有趣的调用,lib/rake/task_manager.rb格式为enhance_with_matching_rule().

于 2014-01-07T14:47:44.573 回答
1

我已经为此苦苦挣扎了一段时间。问题是它rule不允许并行执行其依赖项,同时multitask既不允许基于正则表达式或基于 glob 的匹配,也不允许将 lambdas 作为依赖项。后者只是给你Don't know how to build task '#<Proc:0x007fd95a4ce3f8@/Rakefile:14 (lambda)>' (see --tasks)

我采用的模式是动态组装 MultiTask。以下将匹配“stuff_to_do:12:455:3434”之类的内容并并行执行任务“task_12”、“task_455”和“task_3434”:

rule /stuff_to_do:(:?[0-9]+)+/ => :environment do |t|
     doer = Rake::MultiTask.new("stuff",Rake.application)
     doer.enhance(t.name.split(':')[1..-1].map{|number| "task_#{number}"})
     doer.invoke
  end

结尾

于 2017-06-24T12:20:22.800 回答