1

次のコードでは、次のような出力が期待されます

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 では動作しません。誰かがバグを教えてもらえますか?

4

2 に答える 2

2

VisualWorks は非プリエンプティブ マルチタスキングを使用します。これは、2 つのプロセスが同じ優先度を持つ場合、1 つのプロセスが別のプロセスを実行するために譲歩する必要があることを意味します。次のコードを実行して違いを確認してください。

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.
于 2015-01-02T02:27:40.460 に答える
1

David Buck の答えは完璧です。プロセス スケジューラはプリエンプティブではないため、同じ優先度の 2 つのプロセスは、アクティブなプロセスが準備ができていないセマフォを待機するか、明示的に譲歩しない限り、同時にではなく順次実行されます。

しかし、Pharo と Squeak は同じ非プリエンプティブ スケジューリングを使用しているのに、なぜ違いがあるのでしょうか?
これはモーフィック インタラクションに由来します。どこで、いつ、正確に推測するのは非常に困難です。私はモーフィックの専門家ではありません...
しかし、Transcript ではなく SharedQueue を使用すると、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.
于 2015-01-02T15:36:21.957 に答える