终止所有“主”子线程的正确方法是什么

时间:2019-05-03 20:57:59

标签: ruby multithreading

我正在运行多个线程,并且当其中一个线程将全局函数' $ trade_exected '设置为true时,我希望它杀死所有其他线程并将其从全局'中删除$ threads '数组。

然后我重新启动线程创建过程。

下面是我的代码库的简化版本。

创建了3个线程,看起来好像删除了2个线程,但保留了第三个线程。 (原因未知)

理想情况下,此脚本永远不会输出“ 2”或“ 3”,因为它总是在“ 1”分钟触发,并杀死所有线程并重置。

* 首选 thr.exit 。我不希望在设置 $ trade_executed 后从其他线程通过 thr.join 推送任何代码

require 'thread'

class Finnean 
  def initialize
    @lock = Mutex.new
  end

  def digger(minute)  
    sleep(minute * 60)
    coco(minute)
  end 

  def coco(minute)  
    @lock.synchronize {
    puts "coco #{minute}"

      $threads.each do |thr|
      next if thr == Thread.current
      thr.exit
      end
      $trade_executed = true
      Thread.current.exit   
    } 
  end 
end

minutes = [1, 2, 3]
$threads = Array.new 
$trade_executed = false 
abc = Finnean.new

def start_threads(minutes, abc)
  minutes.each do |minute|
    $threads << Thread.new {abc.digger(minute)}
    puts minute
  end
end

start_threads(minutes, abc)

while true
  if $trade_executed != false then 
    count = 0
    $threads.map! do |thr|
      count += 1
      puts "#{thr} & #{thr.status}"
      thr.exit
      $threads.delete(thr)
      puts "Iteration #{count}"
    end

    count = 0
    $threads.each do |thr|
      count += 1
      puts "#{thr}" ##{thr.status}
      puts "Threads Still Left: #{count}"
    end            

    $trade_executed = false
    abc = Finnean.new
    start_threads(minutes, abc)
  end
end

1 个答案:

答案 0 :(得分:0)

为什么不让线程杀手在第一个完成之前就一直锁住:

# Create two variables that can be passed in to the Thread.new block closure
threads = [ ]
killer = nil

# Create 10 threads, each of which waits a random amount of time before waking up the thread killer
10.times do |n|
  threads << Thread.new do
    sleep(rand(2..25))

    puts "Thread #{n} finished!"
    killer.wakeup
  end
end

# Define a thread killer that will call `kill` on all threads, then `join`
killer = Thread.new(threads) do
  Thread.stop

  threads.each do |thread|
    puts "Killing #{thread}"
    thread.kill
    thread.join
  end
end

# The killer will run last, so wait for that to finish
killer.join

您不能强制线程到exit,但是可以杀死它。这样会生成一个异常,您可以rescue并根据需要进行处理。