這個問題是比較經(jīng)典的啦,基本所有語言的多線程都會涉及到,但是沒想到Lua的這個這么復(fù)雜 抓狂
看了好長時間才算看明白,先上個邏輯圖:
開始時調(diào)用消費者,當消費者需要值時,再調(diào)用生產(chǎn)者生產(chǎn)值,生產(chǎn)者生產(chǎn)值后停止,直到消費者再次請求。設(shè)計為消費者驅(qū)動的設(shè)計。
圖畫的不太好,可以先將Filter遮住,它是過濾器對兩個程序之間傳遞的信息進行處理。去掉Filter邏輯就更清晰些了,就是兩個“線程”(其實是兩個協(xié)同程序)互相調(diào)用。resume回到y(tǒng)ield處開始,支持嵌套,返回到棧頂?shù)膟ield位置。yield是非阻塞的“線程同步”。這到有點像linux里的管道通信。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
function receive(prod) print( "receive is called" ) local status,value = coroutine.resume(prod) return value end function send(x,prod) print( "send is called" ) return coroutine.yield(x) end function producer() return coroutine.create(function () print( "producer is called" ) while true do print( "producer run again" ) local x = io.read() send(x) end end) end function filter(prod) return coroutine.create(function () for line = 1,1000 do print( "enter fliter " ..line) local x = receive(prod) print( "receive in filter finished" ) x= string.format( "%5d %s" ,line,x) send(x,prod) end end) end function consumer(prod) print( "consumer is called" ) while true do print( "consumer run again" ) local x = receive(prod) print( "retrun customer" ) io.write(x, "\n" ) end end p = producer() f=filter(p) consumer(f) |
運行結(jié)果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
consumer is called consumer run again receive is called enter fliter 1 receive is called producer is called producer run again fsy send is called receive in filter finished send is called retrun customer 1 fsy consumer run again receive is called enter fliter 2 receive is called producer run again gaga send is called receive in filter finished send is called retrun customer 2 gaga consumer run again receive is called enter fliter 3 receive is called producer run again ...... |