分类: Python/Ruby
2009-05-08 11:57:25
原作:
翻译:nasi
使用,Python开发者可以在线程之间使用语义来收发消息,就和一样。Erlang就因为其优雅的并行编程内置功能而广受好评。
Erlang系统的妙处在于其简单却很强大。你仅仅需要发送一个消息(message)就可以和另一个线程交互。你根本就不需要关心什么锁(lock)阿、信号量(semaphore)阿、互斥(mutex)阿什么的,就可以在当前的任务中共享信息。开发者们通常仅仅是通过消息传送来实现生产者/消费者模型。但是如果你把消息传递给一个灵活的接收器(Receiver)对象,那功能就强大的多了。比如,使用超时和消息模式,一个线程就可以把消息看成一个状态机或者是一个优先队列。
如果你想更深入的了解Erlang的话,『Concurrent Programming in Erlang』这本书提供一个非常完整的介绍。特别要说的是,Candygram包实现了这本书第5章和第7.2、7.3、7.5节所描述的所有函数。
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 48 49 50 51 52 53 54 55 56 |
import candygram as cg class Thread: """A thread class with just a single counter value and a stop flag.""" def __init__(self): """Initialize counter to zero and stop flag to False.""" self.val = 0 self.stop = False def increment(self): """Increment the counter by one.""" self.val += 1 def sendVal(self, msg): """Send current value of counter to requesting thread.""" req = msg[0] req.send((cg.self(), self.val)) def setStop(self): """Trip the stop flag.""" self.stop = True def run(self): """Entry point of thread.""" # Register the handler functions for various messages: r = cg.Receiver() r.addHandler('increment', self.increment) r.addHandler((cg.Process, 'value'), self.sendVal, cg.Message) r.addHandler('stop', self.setStop) # Keep handling new messages until the stop flag is set. while not self.stop: r.receive() # end while # Create new thread. counter = cg.spawn(Thread().run) # Define a receiver that will return the thread's response values: response = cg.Receiver() response.addHandler((counter, int), lambda msg: msg[1], cg.Message) # Tell thread to increment twice. counter.send('increment') counter.send('increment') # Request thread's current value. counter.send((cg.self(), 'value')) # Print the response print response.receive() # Tell thread to increment one more time. counter.send('increment') # And print it's current value. counter.send((cg.self(), 'value')) print response.receive() # Tell thread to stop. counter.send('stop') |
这是一个使用Candygram在线程间传递消息的非常基本的演示示例。运行这个示例,打印语句会先输出2,然后输出3。
最重要的就是要知道candygram.Receiver这个类是如何工作的。addHandler()方法有2个参数:第一个参数是一个消息模式;第二个则是一个句柄函数。Receiver.receive()这个方法如果发现了一个消息匹配了某个模式,那么它会调用对应的句柄函数并将运行结果返回来。在传给addHandler()的参数中,跟在句柄函数之后的其他参数都在句柄函数被调用的时候作为参数传送给句柄函数。如果参数是candygram.Message常量的话,receive()函数会把这个参数替换成匹配了的消息。
上面的演示包括4种消息模式:’increment’、(cg.Process, ‘value’)、’stop’ 和 (counter, int)。’increment’ 和 ’stop’ 模式是非常简单的模式,可以和 increment’ 及 ’stop’ 字符串直接匹配。(cg.Process, ‘value’)模式将会匹配任何一个将cg.Process的实例作为第一个参数、将字符串 ‘value’ 作为第二个参数的2-元组。最后,(counter, int) 模式将会匹配第一个参数是 ‘counter’ 对象、第二个参数是一个整数的2-元组。