[issue22013] Add at least minimal support for thread groups

Raymond Hettinger report at bugs.python.org
Sun Jul 20 23:45:40 CEST 2014


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 <report at bugs.python.org>
<http://bugs.python.org/issue22013>
_______________________________________


More information about the Python-bugs-list mailing list