Raymond Hettinger added the comment:

> The example looks like something you could use concurrent.futures for

The example was minimal to show how it works.  The concept of having groups of 
related threads is perfectly general.  It is a tool for organizing and 
reasoning about code more complex than this.  

The main virtue is in the aggregate join operation (wait for all workers doing 
a given kind of task to finish).  I believe this is reasonably common (I've 
seen aggregate joins at more than one client). 

The goal is to simplify common patterns of parallel work in phases (each phase 
must be complete before the next phase starts).

Old way:

    phase1_workers = []
    for data in pool:
        t = threading.Thread(target=phase1, args=(data,))
        t.start()
        phase1_workers.append(t)
    for t in phase1_workers:
        t.join()

    phase2_workers = []
    for data in phase1_pool:
        t = threading.Thread(target=phase2, args=(data,))
        t.start()
        phase2_workers.append(t)
    for t in phase2_workers:
        t.join()

    phase3_workers = []
    for data in phase2_pool:
        t = threading.Thread(target=phase3, args=(data,))
        t.start()
        phase3_workers.append(t)
    for t in phase3_workers:
        t.join()

    print('Done')

New way with cleaner code:

    phase1 = SimpleThreadGroup('phase1')
    phase2 = SimpleThreadGroup('phase2')
    phase3 = SimpleThreadGroup('phase3')

    for data in pool:
        t = threading.Thread(phase1, phase1_task, args=(data,)).start()
    phase1.join()

    for data in phase1_pool:
        t = threading.Thread(phase2, phase2_task, args=(data,)).start()
    phase2.join()

    for data in phase2_pool:
        t = threading.Thread(phase3, phase3_task, args=(data,)).start()
    phase3.join()

    print('Done')

The new code is easier to write, to reason about, and to maintain because the 
thread group takes care of building the aggregate collection and applying the 
aggregate join operation to make sure each phase is complete before going on to 
the next phase (i.e. all sprites moved, all user inputs processed, all monsters 
generated, all conflicts resolved, all points accumulated, all bonuses applied, 
...)

As discussed in 
http://journals.ecs.soton.ac.uk/java/tutorial/java/threads/threadgroup.html , 
the feature would be more useful if we had the ability to suspend, resume, or 
stop collections of threads, but our threading have more limited controls 
(check name, get identifier, check whether the thread is alive, and most 
usefully wait for the thread with a join).

For people who write complex multi-threaded code (i.e. my clients), this would 
offer a nice simplification.  I don't see any reason to leave this feature left 
as a stub in perpetuity.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue22013>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to