Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.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 产生多个并行任务_Ruby_Ruby On Rails 3_Parallel Processing - Fatal编程技术网

Ruby 产生多个并行任务

Ruby 产生多个并行任务,ruby,ruby-on-rails-3,parallel-processing,Ruby,Ruby On Rails 3,Parallel Processing,我有M个要处理的任务和N个可用的并行处理资源(想想Heroko或EC2实例上的工作线程),其中M>>N 我可以使用自己的系统,但似乎已经有了一个调试包或gem:你推荐什么?(现在我想起来了,我可以折磨乔布斯这么做了。) 这些任务几乎可以用任何语言编写——甚至一个shell脚本也可以完成这项工作。“母船”是带有PostgreSQL数据库的Ruby On Rails。基本思想是,当资源准备好处理任务时,它向母船请求队列中下一个未处理的任务,并开始处理它。如果工作失败,在放弃之前会重新尝试几次。结果可

我有M个要处理的任务和N个可用的并行处理资源(想想Heroko或EC2实例上的工作线程),其中M>>N

我可以使用自己的系统,但似乎已经有了一个调试包或gem:你推荐什么?(现在我想起来了,我可以折磨乔布斯这么做了。)

这些任务几乎可以用任何语言编写——甚至一个shell脚本也可以完成这项工作。“母船”是带有PostgreSQL数据库的Ruby On Rails。基本思想是,当资源准备好处理任务时,它向母船请求队列中下一个未处理的任务,并开始处理它。如果工作失败,在放弃之前会重新尝试几次。结果可以放入平面文件或写入PostgreSQL数据库


(不,这不是用来产生垃圾邮件的。我正在研究几个大型社交网络。)

听起来你想要一个工作处理器。看看Gearman 相当不懂语言


这是ruby Gem信息,听起来你需要一个作业处理器。看看Gearman 相当不懂语言


这是ruby Gem信息,这是您自己的,但是如果您的并行任务不是资源密集型的,那么它是一个相当快速的解决方案。另一方面,如果它们是资源密集型的,那么您需要实现更健壮的东西

您可以使用
Process::fork
(如果进程在ruby中)或
Process::exec
,或
Process::spawn
(如果进程在其他地方)启动每个线程。然后使用
Process::waitall
完成子流程

下面,我使用了一个
散列
来保存函数本身以及PID。这肯定是可以改进的

# define the sub-processes
sleep_2_fail = lambda { sleep 2; exit -1; }
sleep_2_pass = lambda { sleep 2; exit 0; }
sleep_1_pass = lambda { sleep 1; exit 0; }
sleep_3_fail = lambda { sleep 3; exit -1; }

# use a hash to store the lambda's and their PID's
sub_processes = Hash.new

# add the sub_processes to the hash
#  key = PID
#  value = lambda (can use to be re-called later on)
sub_processes.merge! ({ Process::fork { sleep_2_fail.call } => sleep_2_fail })
sub_processes.merge! ({ Process::fork { sleep_2_pass.call } => sleep_2_pass })
sub_processes.merge! ({ Process::fork { sleep_1_pass.call } => sleep_1_pass })
sub_processes.merge! ({ Process::fork { sleep_3_fail.call } => sleep_3_fail })

# starting time of the loop
start = Time.now

# use a while loop to wait at most 10 seconds or until
# the results are empty (no sub-processes)
while ((results = Process.waitall).count > 0 && Time.now - start < 10) do
  results.each do |pid, status|
    if status != 0
       # again add the { PID => lambda } to the hash
       sub_processes.merge! ( { Process::fork { sub_processes[pid].call } => sub_processes[pid] } )
    end
    # delete the original entry
    sub_processes.delete pid
  end
end
#定义子流程
sleep_2_fail=lambda{sleep 2;exit-1;}
sleep_2_pass=lambda{sleep 2;退出0;}
sleep_1_pass=lambda{sleep 1;退出0;}
sleep_3_fail=lambda{sleep 3;退出-1;}
#使用散列存储lambda及其PID
sub_进程=Hash.new
#将sub_进程添加到哈希中
#键=PID
#value=lambda(可用于稍后重新调用)
sub_进程。合并!({Process::fork{sleep_2_fail.call}=>sleep_2_fail})
sub_进程。合并!({Process::fork{sleep_2_pass.call}=>sleep_2_pass})
sub_进程。合并!({Process::fork{sleep_1_pass.call}=>sleep_1_pass})
sub_进程。合并!({Process::fork{sleep_3_fail.call}=>sleep_3_fail})
#循环开始时间
开始=时间。现在
#使用while循环最多等待10秒或直到
#结果为空(无子进程)
而((results=Process.waitall).count>0&&Time.now-start<10)do
结果.每个do | pid,状态|
如果是状态!=0
#再次将{PID=>lambda}添加到哈希中
sub_进程。合并!({Process::fork{sub_进程[pid].call}=>sub_进程[pid]})
终止
#删除原始条目
sub_进程。删除pid
终止
终止

on
waitall
很有帮助。

这将是您自己的滚动,但是如果您的并行任务不是资源密集型的,那么它是一个相当快速的解决方案。另一方面,如果它们是资源密集型的,那么您需要实现更健壮的东西

您可以使用
Process::fork
(如果进程在ruby中)或
Process::exec
,或
Process::spawn
(如果进程在其他地方)启动每个线程。然后使用
Process::waitall
完成子流程

下面,我使用了一个
散列
来保存函数本身以及PID。这肯定是可以改进的

# define the sub-processes
sleep_2_fail = lambda { sleep 2; exit -1; }
sleep_2_pass = lambda { sleep 2; exit 0; }
sleep_1_pass = lambda { sleep 1; exit 0; }
sleep_3_fail = lambda { sleep 3; exit -1; }

# use a hash to store the lambda's and their PID's
sub_processes = Hash.new

# add the sub_processes to the hash
#  key = PID
#  value = lambda (can use to be re-called later on)
sub_processes.merge! ({ Process::fork { sleep_2_fail.call } => sleep_2_fail })
sub_processes.merge! ({ Process::fork { sleep_2_pass.call } => sleep_2_pass })
sub_processes.merge! ({ Process::fork { sleep_1_pass.call } => sleep_1_pass })
sub_processes.merge! ({ Process::fork { sleep_3_fail.call } => sleep_3_fail })

# starting time of the loop
start = Time.now

# use a while loop to wait at most 10 seconds or until
# the results are empty (no sub-processes)
while ((results = Process.waitall).count > 0 && Time.now - start < 10) do
  results.each do |pid, status|
    if status != 0
       # again add the { PID => lambda } to the hash
       sub_processes.merge! ( { Process::fork { sub_processes[pid].call } => sub_processes[pid] } )
    end
    # delete the original entry
    sub_processes.delete pid
  end
end
#定义子流程
sleep_2_fail=lambda{sleep 2;exit-1;}
sleep_2_pass=lambda{sleep 2;退出0;}
sleep_1_pass=lambda{sleep 1;退出0;}
sleep_3_fail=lambda{sleep 3;退出-1;}
#使用散列存储lambda及其PID
sub_进程=Hash.new
#将sub_进程添加到哈希中
#键=PID
#value=lambda(可用于稍后重新调用)
sub_进程。合并!({Process::fork{sleep_2_fail.call}=>sleep_2_fail})
sub_进程。合并!({Process::fork{sleep_2_pass.call}=>sleep_2_pass})
sub_进程。合并!({Process::fork{sleep_1_pass.call}=>sleep_1_pass})
sub_进程。合并!({Process::fork{sleep_3_fail.call}=>sleep_3_fail})
#循环开始时间
开始=时间。现在
#使用while循环最多等待10秒或直到
#结果为空(无子进程)
而((results=Process.waitall).count>0&&Time.now-start<10)do
结果.每个do | pid,状态|
如果是状态!=0
#再次将{PID=>lambda}添加到哈希中
sub_进程。合并!({Process::fork{sub_进程[pid].call}=>sub_进程[pid]})
终止
#删除原始条目
sub_进程。删除pid
终止
终止

“等待”按钮很有帮助。

我认为这是一项延迟工作或重新确认工作,正如你所说。

我认为这是一项延迟工作或重新确认工作,正如你所说。

同意。我不明白为什么这个解决方案会被认为是“折磨人的”。我的意思是,除了D::J或Resque提供的作业处理之外,还有很多细节需要处理,例如,分配任务和处理错误。但这很可能是我要走的路。接受这个答案。不过,我很可能会使用Amazon的SQS作为整个工作流程的一部分。我不明白为什么这个解决方案会被认为是“折磨人的”。我的意思是,除了D::J或Resque提供的作业处理之外,还有很多细节需要处理,例如,分配任务和处理错误。但这很可能是我要走的路。接受这个答案。不过,我很可能会使用Amazon的SQS作为整个工作流程的一部分。