Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby Rake创建使用多任务的规则_Ruby_Parallel Processing_Rake - Fatal编程技术网

Ruby Rake创建使用多任务的规则

Ruby Rake创建使用多任务的规则,ruby,parallel-processing,rake,Ruby,Parallel Processing,Rake,如果我创建一个简单的规则,比如 rule '.o' => ['.c'] do |t| sh "cc #{t.source} -c -o #{t.name}" end 我怎样才能告诉Rake我希望自动生成的任务是可并行的呢?问题不是很清楚,但Rake::MultiTask不是你想要的吗 我自己也没用过,但医生建议: multitask :copy_files => [:copy_src, :copy_doc, :copy_bin] do puts "All Copies C

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

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

我怎样才能告诉Rake我希望自动生成的任务是可并行的呢?

问题不是很清楚,但Rake::MultiTask不是你想要的吗

我自己也没用过,但医生建议:

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

DSL中
规则
的定义见
lib/rake/DSL_definitions.rb
(在rake 10.1.1中):


不过,对当前代码的粗略扫描不会为DSL中的
规则
构造生成任何内置内容。如果有帮助,可以在代码中搜索
@rules
规则。
lib/rake/task\u manager.rb中生成一个有趣的调用,其形式为
增强与匹配的\u规则()

,如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']
我明白了

具有5个线程:

rake clean
time rake -m -j 5 file.1-20.ext2
我明白了

有20个线程:

rake clean
time rake -m -j 20 file.1-20.ext2
我明白了

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

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

Rake.application.options.always_multitask = true

我已经为此挣扎了一段时间。问题是
规则
不允许并行执行其依赖项,而
多任务
既不允许基于regex或glob的匹配,也不允许lambda作为依赖项。后者只会让您不知道如何构建任务“#”(请参见--tasks)

我采用的模式是动态组装多任务。以下内容将匹配“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

end

可并行化的意思是什么?通过使用Thread.new和“join”-据我所知,他希望为dir中的每个文件并行执行相同的代码。我想知道是否有一个内置原语来实现这一点,比如下面提到的多任务,但对于“规则”任务本质上,我想要的是多任务,但有“规则”任务。i、 e.如果你这样做:rule'.o'=>['.c']do | t |我希望所有的.c文件并行编译,而不是sequentially@alexspeller:我已经有一段时间没有深入研究过Rake的代码了,但如果我没记错的话,规则是执行常规指令集的任务的语法糖。如果您扫描DSL的源代码以查找
def rule
,您可能最终会找到所需的任务语法。如果是这样的话,那么复制它并用多任务替换任务就可以了。@alexspeller:所以…我深入研究了一下,事实上,
rule
似乎只是使用
enhance\u with\u matching\u rule()
扩展了一个任务。我已经更新了我的答案来强调这一点,我怀疑有可能创建或重写内置编译任务,使其跨多个线程运行。(我猜Rake的维护人员会很乐意将它合并到一起,如果它能工作,并且你能成功的话。)感谢大家的关注,我将从那开始进一步研究这个问题point@alexspeller-m将任务转换为多任务,因为规则是任务这也适用于规则,请参阅我的答案以获取一个示例:)非常好-但是有没有一种方法可以默认允许这种行为?我找到了一种方法,这是一个小技巧-但是如果您的Rake文件中有
Rake.application.options.always\u multitask=true
,它将启用此选项。虽然这是不可靠的,因为它不允许命令行以这种方式重写它,但在这个应用程序中我并不担心这一点。
real    0m4.152s
user    0m0.122s
sys     0m0.071s
rake clean
time rake -m -j 20 file.1-20.ext2
real    0m1.167s
user    0m0.130s
sys     0m0.065s
Rake.application.options.always_multitask = true
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