这个问题是比较经典的啦,基本所有语言的多线程都会涉及到,但是没想到Lua的这个这么复杂 抓狂
看了好长时间才算看明白,先上个逻辑图:
开始时调用消费者,当消费者需要值时,再调用生产者生产值,生产者生产值后停止,直到消费者再次请求。设计为消费者驱动的设计。
图画的不太好,可以先将Filter遮住,它是过滤器对两个程序之间传递的信息进行处理。去掉Filter逻辑就更清晰些了,就是两个“线程”(其实是两个协同程序)互相调用。resume回到yield处开始,支持嵌套,返回到栈顶的yield位置。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)
|
运行结果:
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
......
|