Search code examples
smalltalkpharo

Smalltalk Pharo - unable to update a class instance variable in a thread


I have a class called ThreadTesting, and within that class I have an instance variable called 'col' (which is an array). My goal is to populate it through a thread, wait for the thread to finish and then output its contents.

ThreadTesting new callThread.

ThreadTesting class:

initialize
    super initialize.
    semaphore  := Semaphore new.
    col := Array new: 10.

callThread method:

callThread
    self runThread.
    semaphore wait.
    Transcript show: 'Thread finished';cr.
    col  do:
        [ :each |  Transcript show: each ; cr].

runThread method:

runThread
|pr|
pr := [ 

    [ 1 to: 10 do: [ :i |
        col at: i put: i 
        ]].

     semaphore signal.
    ] fork.

Output:

enter image description here

It is all set to nil and I don't know why.


Solution

  • Your problem is simply that you're defining a block that will populate your array, but you're not actually doing anything with it, i.e. it never gets called.

    I think what you want is to simply remove the extra [ and ] around that block, then it will actually be a piece of code that gets executed. You also don't need to assign your outer block to a temporary variable (and if you do want to keep it, please honour the spirit of Smalltalk and call it process, not pr - AAAAB... abbreviations are almost always bad. Similarly, I'd never call an Array something like col - that's misleading and abbreviated...). So your runThread method should look like this:

    runThread
        [
            1 to: 10 do: [ :eachIndex |
                numbers at: eachIndex put: eachIndex
                ].
            semaphore signal
            ] fork
    

    So you're now declaring a block that populates your array and signals your semaphore, and forking it as a new process, whereas previously you were declaring an outer block that declared an inner block (but never did anything with it, it just sat there) and signalled your semaphore, and then forked it as a new process.