Today's Smalltalk 4 You looks more deeply at the process model in Smalltalk, using VA Smalltalk as our example. If you have trouble viewing it here in the browser, you can also navigate directly to YouTube. To watch now, click on the image below:
You can also watch it on YouTube:
Today we'll take a deeper look at processes in VA Smalltalk. We'll be exploring the cooperative process model that VA (and most other Smalltalks) use. First off, we'll set up the following two processes:
"show cooperative processing model" coll := OrderedCollection new. cond1 := 1. proc1 := [[cond1 < 10] whileTrue: [coll add: cond1. cond1 := cond1 + 1]]. proc1 fork. cond2 := 20. proc2 := [[cond2 < 30] whileTrue: [coll add: cond2. cond2 := cond2 + 1]]. proc2 fork. ^coll
When you execute those two, and then inspect the collection, you'll see the following:
Notice that the first process ran to completion before the second one ran. That's because they were both set up at the same priority - unless one of them yields the processor (for IO, or in code purposely), the first will simply run until completion. In the normal Smalltalk process model, only a higher priority process will preempt an existing one. To get a process to yield, use the #yield message, as seen below:
"show cooperative processing model - #yield" coll2 := OrderedCollection new. cond3 := 1. proc3 := [[cond3 < 10] whileTrue: [coll2 add: cond3. cond3 := cond3 + 1. Processor yield]]. proc3 fork. cond4 := 20. proc4 := [[cond4 < 30] whileTrue: [coll2 add: cond4. cond4 := cond4 + 1. Processor yield]]. proc4 fork. ^coll2That gives us the following:
With the #yield being used, each process waits for any otter process (at the same or lower priority) to have a shot at the processor. What if one process is at a higher priority?
"show cooperative processing model - higher priority" coll3 := OrderedCollection new. cond5 := 1. proc5 := [[cond5 < 10] whileTrue: [coll3 add: cond5. (Delay forSeconds: 1) wait. cond5 := cond5 + 1]]. proc5 fork. cond6 := 20. proc6 := [[cond6 < 30] whileTrue: [coll3 add: cond6. cond6 := cond6 + 1]]. proc6 forkAt: Processor userInterruptPriority. ^coll3
The Delay is used in the first process so that it doesn't run to completion before we even start executing the second process. The results are shown below:
The first process starts running, goes into a wait state (the Delay), and then never gets the processor back so long as the higher priority process runs. That's how the scheduler works in Smalltalk.
Finally, what if you have a long running process that you need to kill? Simple - use #terminate:
"kill a process" proc7 := [[true] whileTrue: [(Delay forSeconds: 2) wait. Transcript show: 'Executing...'; cr]] forkAt: Processor userBackgroundPriority. proc7 terminate.
Need more help? There's a screencast for other topics like this which you may want to watch. Questions? Try the "Chat with James" Google gadget over in the sidebar.
[st4u186-iPhone.m4v ( Size: 9254001 )]