Pharo与Smalltalk的区别

7

我试图在Pharo中使用 promises/futures扩展功能。我发现了这个网站http://onsmalltalk.com/smalltalk-concurrency-playing-with-futures,它实现了Smalltalk的futures。然而,当我将这部分代码复制到Pharo中时,遇到了一些错误:

value: aBlock 
promiseLock  := Semaphore new.

[ [ promiseValue := aBlock value ] 
    on: Error
    do: [ :err | promiseError  := err ]
    ensure: [ promiseLock signal ] ] forkBackground

以下是错误信息:

[forkBackground] Messages sent but not implemented 
[on:do:ensure:] Messages sent but not implemented

我认为Pharo与Smalltalk没有什么不同,或者说这个网站的解决方案也适用于Smalltalk。


1
关于“Pharo与Smalltalk没有区别”这一说法...如今,Smalltalk更多地是一个概念。许多方言甚至连相同的语法都没有,更不用说API/标准库了。 - Peter Uhnak
2个回答

6

请尝试以下方法:

promiseLock := Semaphore new.
[
  [[promiseValue := aBlock value] on: Error do: [:err | promiseError := err]]
    ensure: [promiseLock signal]] forkAt: Processor userBackgroundPriority

这个想法是确保promiseLock信号量即使出现Error也能接收到signal,以确保对aBlock的评估不受影响。在forkAt:的优先级是有争议的,但我会从某个地方开始,并根据需要进行调整。


我有一个与此承诺实现相关的进一步问题,该问题位于https://dev59.com/N6rka4cB1Zd3GeqPjc5C上。 - Gakuo

0
来晚了,但有一本电子书可以直接讨论Pharo中的这个问题,并提供了确切的解决方案。我知道它有效,因为我曾经使用过它。

https://books.pharo.org/booklet-ConcurrentProgramming/

这个解决方案直接来自于那本书,我并没有发明它。

解决方案涉及向类 BlockClosure 添加两个信息。

BlockClosure >> promise
^ self promiseAt: Processor activePriority

并且:

BlockClosure >> promiseAt: aPriority
"Answer a promise that represents the result of the receiver
execution
at the given priority."
| promise |
promise := Promise new.
[ promise value: self value ] forkAt: aPriority.
^ promise

创建一个 Promise 类。
Object subclass: #Promise
instanceVariableNames: 'valueProtectingSemaphore value hasValue'
classVariableNames: ''
package: 'Promise'

Promise >> initialize
super initialize.
valueProtectingSemaphore := Semaphore new.
hasValue := false

Promise >> hasValue
^ hasValue

Promise >> value
"Wait for a value and once it is available returns it"
valueProtectingSemaphore wait.
valueProtectingSemaphore signal. "To allow multiple requests for
the value."
^ value

Promise >> value: resultValue
value := resultValue.
hasValue := true.
valueProtectingSemaphore signal

我在实现MQTT数据读取器时使用了这个。我会向Broker请求最新的消息并返回一个Promise。这样我就可以循环使用Promise而不阻塞图像中运行的其他进程。
它的效果非常好。虽然我花了一些时间来理解它的工作原理,但并不难。
你可以通过将你的操作放在一个块中并发送给Promise方法来使用它。
myPromise := [broker readMessage ] promise.
你也可以进行测试:
(myPromise hasValue) ifTrue: [ 
    myObject processMsg: (myPromise value)
]

你应该将任务放在自己的线程中,以防止阻塞图像的其余部分。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接