如果我创建一个像
这样的简单规则rule '.o' => ['.c'] do |t|
sh "cc #{t.source} -c -o #{t.name}"
end
如何告诉Rake我希望自动生成的任务可以并行化?
答案 0 :(得分: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)模拟&#39; work / io&#39;,如果你的进程阻塞了很多,或者你有很多核心,这可能对你有用:)
编辑:正如Shadow在评论中所指出的,以下是切换多任务&#39;总是在
Rake.application.options.always_multitask = true
答案 1 :(得分: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中rule
的定义位于lib/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
对当前代码的粗略扫描不会为DSL中的rule
构造产生内置任何内容。如果它有帮助,搜索@rules
和rules.
之类的代码会在lib/rake/task_manager.rb
中以enhance_with_matching_rule()
的形式产生一个有趣的调用。
答案 2 :(得分:0)
我一直在努力解决这个问题。问题是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
端