Multiple processes using #nextPutAll:
Andreas Raab
andreas.raab at gmx.de
Tue May 29 07:40:24 UTC 2007
Yes, that is a very clever solution. You could tidy this up a little by
using:
Array subclass: #YieldingArray
instanceVariableNames:''
classVariableNames: ''
poolDictionaries: ''
category: 'Temp'
YieldingArray>>do: aBlock
"Evaluate aBlock with all the arguments. Yield in the middle."
1 to: self size do:[:i|
aBlock value: i.
Processor yield.
].
#yield will take care of things without a semaphore due to Squeak's
process scheduling rules.
Cheers,
- Andreas
Martin v. Löwis wrote:
>> queue := self newQueue.
>> writingBlock := [queue nextPutAll: (1 to: 10000)].
>> writingBlock
>> fork;
>> fork;
>> fork.
>> Processor yield.
>> self assert: (queue next: 10000) asArray = (1 to: 10000) asArray.
>> self assert: (queue next: 10000) asArray = (1 to: 10000) asArray.
>> self assert: (queue next: 10000) asArray = (1 to: 10000) asArray.
>> self assert: queue atEnd.
>>
>>
>> I assume it's because when I fork, the work is done before the
>> following fork starts.
>>
>> Can somebody help me writing this test?
>
> I assume that nextPutAll: relies on do: to fetch all elements of
> the collection. So you could define a BlockingCollection, which
> contains a collection, and a semaphore as instance variables.
> Then, do: would do
>
> do: aBlock
> collection do:[:each|
> semaphore wait.
> aBlock value: each.
> semaphore signal.
> ].
>
> Alternatively, if it relies on at: also implement
>
> at: index
> | result |
> semaphore wait.
> result := collection at: index.
> semaphore signal.
> ^result.
>
> Then, in the test, you do
>
> sem := Semaphore new.
> writingBlock := [queue nextPutAll:
> (BlockingCollection on: (1 to: 10000) with: sem)].
> sem signal.
>
> HTH,
> Martin
>
>
>
More information about the Squeak-dev
mailing list
|