2014-02-23 92 views
5

我想從不同的線程調用一個普通的枚舉器。當我這樣做,跨主題共享一個枚舉器

enum = (0..1000).to_enum 
t1 = Thread.new do 
    p enum.next 
    sleep(1) 
end 
t2 = Thread.new do 
    p enum.next 
    sleep(1) 
end 
t1.join 
t2.join 

它提出了一個錯誤:

Fiber called across threads. 

enumt2一次後調用從t1被調用。

  • 爲什麼紅寶石設計成不允許枚舉(或光纖)在線程被調用,並
  • 是否有以提供類似的功能的另一種方式?

我猜測枚舉器/光纖操作的原子性在這裏是相關的,但我不完全確定。如果這是問題,那麼在使用時獨佔鎖定枚舉器/光纖將解決問題,並且我不知道爲什麼通常禁止跨線程調用枚舉器/光纖。如果可以通過使用鎖定來提供替代方案,那將滿足我的需要。

+0

將隊列滿足您的需求? –

+0

@UriAgassi如果你可以做到這一點,它會。 – sawa

+0

@sawa,你最終做了什麼? –

回答

2

您可以使用Queue

queue = Queue.new 
(0..1000).map(&queue.method(:push)) 

t1 = Thread.new do 
    while !queue.empty? 
    p queue.pop(true) 
    sleep(0.1) 
    end 
end 
t2 = Thread.new do 
    while !queue.empty? 
    p queue.pop(true) 
    sleep(0.1) 
    end 
end 
t1.join 
t2.join 
+0

我希望能夠重用它。通過彈出,它會改變。 – sawa

+0

會發生什麼變化? –

+0

這將取代枚舉數,而不是數組/範圍/無論......而不是'rewind' - 重建它 –