Smalltalk Visual Works 并发

Smalltalk Visual Works concurrency

使用以下代码,我希望输出像

AA
BB
AA
AA
AA
BB

代码:

p1 := [ 1 to: 3000 do: [:i | Transcript show: 'AA';cr.] ] newProcess.
p2 := [ 5000 to: 8100 do: [:i | Transcript show: 'BB';cr.] ] newProcess. 
p1 resume.
p2 resume.

但它首先打印所有 AA,然后打印所有 BB。 在 Pharo 下工作正常,但不是 VisualWorks。有人可以告诉错误吗?

VisualWorks 使用非抢占式多任务 这意味着当两个进程具有相同的优先级时,一个进程需要让步才能让另一个进程 运行。尝试 运行 执行以下代码以查看区别:

p1 := [ 1 to: 3000 do: [:i |
    Transcript show: 'AA';cr.
    i \ 10 = 0 ifTrue: [Processor activeProcess yield]] ] newProcess.
p2 := [ 5001 to: 8101 do: [:i |
    Transcript show: 'BB';cr.
    i \ 10 = 0 ifTrue: [Processor activeProcess yield]] ] newProcess. 
p1 resume.
p2 resume.

David Buck 的回答是完美的:进程调度程序不是抢占式的,所以两个相同优先级的进程将 运行 顺序地而不是并发地,除非活动进程将等待一个非就绪的信号量或显式产量。

但是 Pharo 和 Squeak 使用相同的非抢占式调度,所以为什么不同?
它来自Morphic交互,很难准确猜测where/when,我不是Morphic专家...
但是,如果您使用 SharedQueue 而不是 Transcript,您将获得与 Visualworks 相同的行为,所有 'AA' 然后所有 'BB':

q := SharedQueue new: 6101.
s1 := Semaphore new.
s2 := Semaphore new.
p1 := [ 1 to: 3000 do: [:i | q nextPut: 'AA']. s1 signal ] newProcess.
p2 := [ 5000 to: 8100 do: [:i | q nextPut: 'BB'.]. s2 signal ] newProcess. 
p1 resume.
p2 resume.
s1 wait.
s2 wait.
q inspect.