How to use two threads (GUI and backend)

Marko Rauhamaa marko at pacujo.net
Wed Oct 26 10:21:39 EDT 2016


Chris Angelico <rosuav at gmail.com>:

> On Thu, Oct 27, 2016 at 12:37 AM, Marko Rauhamaa <marko at pacujo.net> wrote:
>> I don't know what "Global state is shared across all threads" means
>> in this context. It sounds like something that would be true for,
>> say, Java and C as well. However, those languages don't promise to
>> propagate improperly synchronized changes between threads.
>>
>> Now I would like to ask for some documentation.
>
> Here you have two functions and a global:
>
> active = True
>
> def func1():
>     while active:
>         # do work
>         time.sleep(1)
>         func2()
>
> def func2():
>     global active
>     if random.random() < 0.1:
>         active = False

The thread version:

========================================================================
   active = True

   class T1(threading.Thread):
       def run(self):
           while active:
               # do work
               time.sleep(1)

   class T2(threading.Thread):
       def run(self):
           global active
           if random.random() < 0.1:
               active = False

   t1, t2 = T1(), T2()
   t1.start()
   t2.start()
   t1.join()
   t2.join
========================================================================

Analogous code in C or Java would not be guaranteed to finish if func1()
and func2() were in different execution contexts. In fact, it would be
almost guaranteed to hang.

That is because the compiler can see that "active" cannot change within
T1.run() and would rewrite the code as:

========================================================================
   class T1(threading.Thread):
       def run(self):
           if active:
               while True:
                   # do work
                   time.sleep(1)
========================================================================

Similarly, setting a flag in a signal handler might not be noticed by
the main program if it were written in C. (You need to mark the variable
as volatile.)

> I'm sure you understand that these functions share the global state of
> the 'active' flag. One changes it, the other sees the change. So far,
> nothing controversial or difficult.
>
> It's exactly the same with threads.

Extraordinary claims require extraordinary evidence.

   <URL: http://stackoverflow.com/questions/3549833/python-threading-memo
   ry-model-and-visibility>

Now, Jython developers guarantee the volatility of all memory access.
They even state this as normative for Python:

   The fundamental thing to know about Python, and what we have
   implemented in Jython, is that setting any attribute in Python is a
   volatile write; and getting any attribute is a volatile read.

   [...]

   This means that safe publication is pretty much trivial in Python,
   when compared to Java. Safe publication means the thread safe
   association of an object with a name. [...] this is always a
   memory-fenced operation in Python

   <URL: http://www.jython.org/jythonbook/en/1.0/Concurrency.html>


Marko



More information about the Python-list mailing list