Hi Alastair, >> On Jan 12, 2020, at 12:34 AM, Alistair Grant <[email protected]> wrote: > On Thu, 9 Jan 2020 at 13:01, ducasse <[email protected]> wrote: >> >> Hi >> >> I wanted to explain >> >> | semaphore p1 p2 | >> semaphore := Semaphore new. >> p1 := [ semaphore wait. >> 'p1' crTrace ] fork. >> >> p2 := [semaphore signal. >> 'p2' crTrace ] fork. >> >> displays p2 and p1. >> but I would like explain clearly but it depends on the semantics of signal. > > The way this is phrased seems to imply that 'p2' will always be > displayed before 'p1', however in Pharo this is not guaranteed (when > the processes are at the same priority, as they are this example). > > As Eliot implied in another reply, Pharo has #processPreemptionYields > set to true, which means that any time a higher priority process > preempts, the current process will be moved to the back of the queue. > > So in the case above, after p2 signals the semaphore, if a timer was > delivered or keystroke pressed, p2 would be suspended and moved to the > back of the queue. When the timer / keystroke / etc. had finished > processing p1 would be at the front of the queue and would complete > first. > > Since time and input events are (for practical purposes) unpredictable > it means that the execution order of processes at a given priority is > also unpredictable. > > While this isn't likely to happen in the example above, I have seen it > regularly with TaskIt and multiple entries being run concurrently. > > I agree with Eliot that changing #processPreemptionYields to true by > default would be an improvement in Pharo. It would make it easier to > predict what is happening in a complex environment
You mean to write that “I agree with Eliot that changing #processPreemptionYields to false by default would be an improvement in Pharo. It would make it easier to predict what is happening in a complex environment.” Preemption by a higher priority process should not cause a yield. > Running the following variant, and then typing in to another window, > demonstrates the behaviour: > > | semaphore p1 p2 | > semaphore := Semaphore new. > [ 100 timesRepeat: [ > p1 := [ | z | > semaphore wait. > z := SmallInteger maxVal. > 10000000 timesRepeat: [ z := z + 1 ]. > 'p1' crTrace ] fork. > > p2 := [ | z | 1 second wait. > semaphore signal. > z := SmallInteger maxVal. > 10000000 timesRepeat: [ z := z + 1 ]. > 'p2' crTrace ] fork. > 1 second wait. > ] ] fork. > > > The tail of transcript: > > 'p2' > 'p1' > 'p1' > 'p1' > 'p1' > 'p2' > 'p2' > 'p2' > 'p1' > 'p1' > 'p2' > 'p1' > 'p2' > 'p2' > 'p1' > 'p1' > 'p2' > 'p1' > > > > Cheers, > Alistair Cheers, Alistair! _,,,^..^,,,_ (phone)
