Michael van der Gulik posted some code that runs a number of processes, and wondered about the results - which showed that the processes don't all run:
- My code is borked, which is entirely possible,
- The ProcessScheduler is buggy, or
- Squeak is meant to work like this.
Which of those is true?
I haven't examined the scheduler in Squeak, but in VW (which is descended from the same original codebase), processes are cooperative - i.e., a process at priority N will never interrupt another process at priority N. So in VW, when I tried his test, only one of the processes ever ran. He set up N processes, and had them fork like this:
loop: element [[ continue ] whileTrue: [ counts at: element put: ((counts at: element) + 1). ] ] forkAt: 10.
So if I do that, only the first one in ever runs (as they never get blocked on i/o). To make them all run, you do something like this:
loop: element [[ continue ] whileTrue: [ counts at: element put: ((counts at: element) + 1). Processor activeProcess yield. ] ] forkAt: 10.
That #yield puts the process in question on hold, allowing others to run. This is simply the way VW (and, to a large extent, it seems) Squeak work. If you want pre-emptive scheduling, it's easy enough to do - just change the scheduler (all the code is there in Smalltalk).