[Tutor] Changing instance attributes in different threads
Kent Johnson
kent37 at tds.net
Tue Feb 7 12:31:05 CET 2006
Bernard Lebel wrote:
> Hi Kent,
>
> I have put together a little script to give a rough idea about what
> the program does.
>
> http://www.bernardlebel.com/scripts/nonxsi/help/bl_threadtest.py
In this code, there is no guarantee that callMeWhenAttributeChanged()
will see every change to oBernard.firstname. It could change more than
once while checkFirstName() is sleeping and looping. The change to
oBernard.firstname in main could stomp on a change from
changeAttribute() before it is seen in checkFirstName().
I don't know what the consequences of missing a change are. If the names
are some kind of command token I would use a Queue - in this example you
have two producers and one consumer, a Queue will ensure that every
command is seen. If there is no consequence of missing a change you
could leave it as-is or use a threading.Condition to replace the polling
loop with wait() / notify().
>
>
> The true program does this:
>
> - the top program file imports a module called fcJob
>
> - the top program instantiate the only class in the fcJob module. The
> class is named fcJob as well, the instance is named simply "job". This
> instance has few attribute, the one that I'm interested in now is
> "localjobstatus".
>
> - the top program file enters a while loop where it checks a variety
> of things, and if certain conditions are met, will start a big
> function in a separate thread.
>
> - the function that runs in the separate thread reads and writes the
> localjobstatus attributes.
>
> - while the child thread is running, the main thread checks a database
> every 5 seconds to test the value of certain fields.
>
> - would the value of specific field changed to certain values, the top
> thread will set the localjobstatus value to something like "killed".
>
> - the child thread, also running a while loop, tests the local job
> attribute at 3 times during a single iteration. If it gets a "Killed"
> value, it will call a function that basically terminates this child
> thread in a clean way. Ultimately, it will set the localjobstatus to
> "Pending".
This sounds unsafe. What happens if the "Pending" value is overwritten
by another "Killed" value? It might be fine if you use two different
status variables.
When working with threads you have to imagine what would happen if one
thread stopped indefinitely at any point, and another thread ran long
enough to do something unexpected. Or two threads interleave statements
in the worst possible way. Your code seems to have several opportunities
for bad things to happen. I can't tell what the consequences of them
are, which will determine how hard you should work to prevent them.
HTH
Kent
More information about the Tutor
mailing list