Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
Multithreading 杀死水晶郎中的一根线_Multithreading_Crystal Lang - Fatal编程技术网

Multithreading 杀死水晶郎中的一根线

Multithreading 杀死水晶郎中的一根线,multithreading,crystal-lang,Multithreading,Crystal Lang,我写了一个程序一个水晶程序用筛子计算一个范围内的素数 代码 我想展示它的方式是 问题 问题是当puts编写筛选时线程没有被终止。方法sieve(n)只返回一个数组。然后计算并打印阵列大小。您可以看到动画冻结一段时间,然后继续,直到打印并退出。如果使用spawn do…endspawn中的打印将暂停,直到计算出筛子 不杀死线程会导致这样的问题 我以前用ruby做的 t = Thread.new { loop while ... } <some other time consuming s

我写了一个程序一个水晶程序用筛子计算一个范围内的素数

代码 我想展示它的方式是

问题 问题是当puts编写筛选时线程没有被终止。方法sieve(n)只返回一个数组。然后计算并打印阵列大小。您可以看到动画冻结一段时间,然后继续,直到打印并退出。如果使用
spawn do…end
spawn中的打印将暂停,直到计算出筛子

不杀死线程会导致这样的问题

我以前用ruby做的

t = Thread.new { loop while ... }
<some other time consuming stuff here>

t.kill
return calculated_stuffs
t=Thread.new{loop while…}
t、 杀死
返回已计算的物品
水晶细节 水晶0.31.1(2019-10-21)

LLVM:9.0.0 默认目标:x86_64-pc-linux-gnu



如何杀死crystal中的线程?

thread
是crystal内部API的一部分,不打算直接使用

好消息是Crystal本机支持一个名为的并发模型,其中光纤(轻量级线程)通过线程安全通道相互发送消息,以便进行协调。因此,光纤不是通过共享状态进行通信,而是通过通信来共享状态——正如他们在《golang》中所说的那样

对于您的用例,您可以运行3种光纤:

  • 筛选,生成数字并通过通道发送更新
  • 监视器,在筛选通道上接收,更新UI,并在筛选完成后发送完成消息
  • 主光纤,等待监视器通知完成,并能够决定如何处理筛子的结果

下面是您的代码可能的样子

record Result, primes : Array(Int32)
record Tick
alias SieveUpdate = Result | Tick

def monitor(updates : Channel(SieveUpdate)) : Channel(Result)
  Channel(Result).new.tap { |done|
    spawn do
      dot, ary, colours = ".", ["\xE2\xA0\x81", "\xE2\xA0\x88", "\xE2\xA0\xA0", "\xE2\xA0\x84"] * 2, [154, 184, 208, 203, 198, 164, 129, 92]
      ary_idx = 0
      update_n = 0
      print "\e[?25l"
      loop do
        case value = updates.receive
        when Tick
          next unless (update_n+=1) % 50 == 0 # lower refresh rate
          print("\e[2K#{ary[ary_idx]} \e[38;5;#{colours[ary_idx]}mPlease Wait#{dot * ary_idx}\e[0m\r")
          ary_idx = (ary_idx + 1) % ary.size
        when Result
          puts "\e[?25h"
          done.send value
          break
        end
      end
    end
  }
end

def sieve(max) : Channel(SieveUpdate)
  Channel(SieveUpdate).new.tap { |updates|
    spawn do
      s = [nil, nil] + (2..max).to_a
      s.each do |x|
          updates.send(Tick.new)
          next unless x
          break if (sq = x ** 2) > max
          (sq..max).step(x) { |y| s[y] = nil }
      end

      updates.send Result.new(s.compact.as(Array(Int32)))
    end
  }
end

updates = sieve(2_000_000)
done = monitor(updates)

print done.receive.primes.size
你可以添加一个布尔值“keep_running”或一个你可以向该线程发送消息的通道,比如“stop running”并每隔一段时间轮询一次,FWIW。。。
record Result, primes : Array(Int32)
record Tick
alias SieveUpdate = Result | Tick

def monitor(updates : Channel(SieveUpdate)) : Channel(Result)
  Channel(Result).new.tap { |done|
    spawn do
      dot, ary, colours = ".", ["\xE2\xA0\x81", "\xE2\xA0\x88", "\xE2\xA0\xA0", "\xE2\xA0\x84"] * 2, [154, 184, 208, 203, 198, 164, 129, 92]
      ary_idx = 0
      update_n = 0
      print "\e[?25l"
      loop do
        case value = updates.receive
        when Tick
          next unless (update_n+=1) % 50 == 0 # lower refresh rate
          print("\e[2K#{ary[ary_idx]} \e[38;5;#{colours[ary_idx]}mPlease Wait#{dot * ary_idx}\e[0m\r")
          ary_idx = (ary_idx + 1) % ary.size
        when Result
          puts "\e[?25h"
          done.send value
          break
        end
      end
    end
  }
end

def sieve(max) : Channel(SieveUpdate)
  Channel(SieveUpdate).new.tap { |updates|
    spawn do
      s = [nil, nil] + (2..max).to_a
      s.each do |x|
          updates.send(Tick.new)
          next unless x
          break if (sq = x ** 2) > max
          (sq..max).step(x) { |y| s[y] = nil }
      end

      updates.send Result.new(s.compact.as(Array(Int32)))
    end
  }
end

updates = sieve(2_000_000)
done = monitor(updates)

print done.receive.primes.size