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,如何在每个线程中设置ENV变量?_Ruby_Multithreading - Fatal编程技术网

ruby,如何在每个线程中设置ENV变量?

ruby,如何在每个线程中设置ENV变量?,ruby,multithreading,Ruby,Multithreading,我正在尝试使用x2.rb之类的线程并行运行ruby代码。 为了解决我的问题,我在这里粘贴了一个尽可能简单的示例代码。 在这里,我不明白为什么每个线程的ENV设置不不同。我一直被这个困扰着。有人能帮我吗? 如果不解决这个问题,我就不能使用线程 # ./x1.rb test1 a .. a .. {"TEST"=>"a"} test1 b .. b .. {"TEST"=>"b"} test1 c .. c .. {"TEST"=>"c"} # ./x2.rb test1 a

我正在尝试使用x2.rb之类的线程并行运行ruby代码。 为了解决我的问题,我在这里粘贴了一个尽可能简单的示例代码。 在这里,我不明白为什么每个线程的ENV设置不不同。我一直被这个困扰着。有人能帮我吗? 如果不解决这个问题,我就不能使用线程

# ./x1.rb
test1 a .. a .. {"TEST"=>"a"}
test1 b .. b .. {"TEST"=>"b"}
test1 c .. c .. {"TEST"=>"c"}

# ./x2.rb

test1 a .. a .. {"TEST"=>"c"}       # this needs to be {"TEST"=>"a"}
test1 b .. b .. {"TEST"=>"c"}       # this needs to be {"TEST"=>"b"}
test1 c .. c .. {"TEST"=>"c"}       # this needs to be {"TEST"=>"c"}

x1.rb:

#!/usr/bin/ruby

test_hash = {'a': 1, 'b': 2, 'c': 3}

def test_env(k, v)
  ENV.clear
  ENV['TEST'] = k.to_s
  print "test1 #{k} .. #{ENV['TEST']} .. "
  p ENV
  # run_cmd(ENV, "cmd to run")
end

test_hash.each do |k, v|
  test_env(k, v)
end

x2.rb:

#!/usr/bin/ruby

test_hash = {'a': 1, 'b': 2, 'c': 3}
threads = []

def test_env(k, v)
  ENV.clear
  ENV['TEST'] = k.to_s
  print "\ntest1 #{k} .. #{ENV['TEST']} .. "
  p ENV
  # run_cmd(ENV, "cmd to run")
end

test_hash.each do |k, v|
  threads << Thread.new(k, v)  do |k, v|
    test_env(k, v)
  end
end

threads.each(&:join)
#/x1.rb
测试1 a。。A.{“TEST”=>“a”}
测试1b。。B{“测试”=>“b”}
测试1 c。。C{“测试”=>“c”}
#./x2.rb
测试1 a。。A.{“TEST”=>“c”}#这需要是{“TEST”=>“a”}
测试1b。。B{“TEST”=>“c”}#这需要是{“TEST”=>“b”}
测试1 c。。C{“TEST”=>“c”}#这需要是{“TEST”=>“c”}
x1.rb:
#!/usr/bin/ruby
test_hash={'a':1,'b':2,'c':3}
def测试环境(k,v)
环境清洁
环境['TEST']=k.to_
打印“test1{k}..{ENV['TEST']}..”
p环境
#运行命令(环境,“命令运行”)
结束
测试每个do | k,v|
测试环境(k,v)
结束
x2.rb:
#!/usr/bin/ruby
test_hash={'a':1,'b':2,'c':3}
线程=[]
def测试环境(k,v)
环境清洁
环境['TEST']=k.to_
打印“\ntest1{k}..{ENV['TEST']}..”
p环境
#运行命令(环境,“命令运行”)
结束
测试每个do | k,v|

线程如果您像这样加入线程,它将工作:

test_hash.each do |k, v|
  Thread.new(k, v)  do |k, v|
    test_env(k, v)
  end.join
end

线程不同于单独的子shell或单独调用Ruby和脚本,也不是并行的;它们共享相同的解释器、环境和
ENV
。“如果不解决这个问题,我就不能使用线程。”嗯,这很有戏剧性。线程并不是每个问题的解决方案,但它们非常有用,但是如果不了解您的目标,我们就帮不了多少忙。也许您使用线程的决定导致了“”的结果,可能还有更好的方法。@Jon:可能是通过使用打算以这种方式使用的数据库软件/api。我知道这听起来很不屑一顾,但有一点超出了这一点,试图将软件扭曲到它不是为之设计的环境中是不值得的,除非你在做遗留维护。哦,天哪。我迫不及待地想让您知道MRI ruby线程不是并行执行的,它们受到全局解释器锁的约束。如果您试图跨实例数组并行SQL查询,并且使用Ruby作为并行工具,那么您一定会与工程学产生很大分歧。@Jon:即使在不是MRI的Ruby实现上(人们使用的一个post,甚至没有真正的线程),线程也将是主进程的子进程/线程,因此,它将在我能想到的任何系统上共享它的环境变量。然而,有可能(尽管我不记得细节)在不改变您的环境变量的情况下产生另一个具有不同于您自己的环境变量的进程,我觉得这是您实际需要做的。这里还有另一个想法:与其坚持使用ENV或参数,不如将配置数据写入文件。在主线程中加载它,并根据配置生成工作线程。不过,你还是在用扳手做心脏直视手术。