Ba7*_*chy 7 multithreading coroutine crystal-lang
我很难学习Fibers\coroutines背后的想法和Crystal中的实现.
我希望这是一个正确的问题,我完全接受"不在这里"的答案:)
这是我在Ruby中处理多线程的常用方法:
threads = []
max_threads = 10
loop do
begin
threads << Thread.new do
helper_method(1,2,3,4)
end
rescue Exception => e
puts "Error Starting thread"
end
begin
threads = threads.select { |t| t.alive? ? true : (t.join; false) }
while threads.size >= max_threads
puts 'Got Maximum threads'
sleep 1
threads = threads.select { |t| t.alive? ? true : (t.join; false) }
end
rescue Exception => e
puts e
end
end
Run Code Online (Sandbox Code Playgroud)
这样我打开一个新的线程,通常是传入的连接或其他东西,将线程添加到线程数组,然后检查我没有更多的线程,然后我想要的.
使用spawn\channels\fiber等在Crystal中实现类似功能的好方法是什么?
waj*_*waj 15
像这样的东西:
require "socket"
ch = Channel(TCPSocket).new
10.times do
spawn do
loop do
socket = ch.receive
socket.puts "Hi!"
socket.close
end
end
end
server = TCPServer.new(1234)
loop do
socket = server.accept
ch.send socket
end
Run Code Online (Sandbox Code Playgroud)
此代码将预生成10个光纤以参加请求.该通道是无缓冲的,因此如果它们不能被任何光纤接收,则连接将不会排队.
你不能复制它对线程的工作方式.spawn不返回协程对象,并且没有办法join协同处理.
然而,我们可以在协同程序和池管理器之间建立通道.这个经理可以在它自己的协程中运行,也可以作为主协程 - 这将阻止进程退出.
这是一个工作示例,其中一个worker(&block)方法将生成一个协程,并打开一个通道来返回其状态(它失败或终止),以及一个pool(&block)方法,它将保留这些工作池并从结果通道中读取知道协同程序的状态,并继续产生新的协同程序.
def worker(&block)
result = UnbufferedChannel(Exception?).new
::spawn do
begin
block.call
rescue ex
result.send(ex)
else
result.send(nil)
end
end
result
end
def pool(size, &block)
counter = 0
results = [] of UnbufferedChannel(Exception?)
loop do
while counter < size
counter += 1
puts "spawning worker"
results << worker(&block)
end
result = Channel.select(results)
counter -= 1
results.delete(result)
if ex = result.receive
puts "ERROR: #{ex.message}"
else
puts "worker terminated"
end
end
end
pool(5) do
loop { helper_method(1, 2, 3, 4) }
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1979 次 |
| 最近记录: |