You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add at least minimal support for thread groups #66212
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee=Noneclosed_at=<Date2022-03-21.23:58:55.255>created_at=<Date2014-07-20.06:56:34.045>labels= ['type-feature', 'library']
title='Add at least minimal support for thread groups'updated_at=<Date2022-03-21.23:58:55.254>user='https://github.com/rhettinger'
Currently, threading.Thread requires that group=None pending implementation of a ThreadGroup class such as that described in http://www.javaworld.com/article/2074481
This has been an open todo for very long time, possibly because it may be too big of a task to implement all the features including subgroups.
I think we can implement a small but useful set of features without too much difficultly:
path_explorers=threading.ThreadGroup('path_explorers')
forpathinpaths:
threading.Thread(path_explorers, explore, (path,))
forthreadinpath_explorers: # enumerate unfinished explorersprint(thread)
path_explorers.start() # begin parallel searchpath_explorers.join() # wait for group to finishprint("Result:", best_path)
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).
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.
For your examples, my first instinct would be to use a thread pool executor. It's a nice high level API and can already do the aggregate join.
PCManticore commented on Jul 20, 2014
PCManticoremannequin
Mannequin
More actions
This seems indeed like a weaker version of ThreadPoolExecutor. Here's how your example looks with it, not very different and still easy to understand and grasp:
Activity
rhettinger commentedon Jul 20, 2014
Currently, threading.Thread requires that group=None pending implementation of a ThreadGroup class such as that described in http://www.javaworld.com/article/2074481
This has been an open todo for very long time, possibly because it may be too big of a task to implement all the features including subgroups.
I think we can implement a small but useful set of features without too much difficultly:
pitrou commentedon Jul 20, 2014
I have a hard time understanding what it would bring in Python's context. Even the Java API doesn't look very useful.
bitdancer commentedon Jul 20, 2014
The example looks like something you could use concurrent.futures for and get more features besides?
rhettinger commentedon Jul 20, 2014
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:
New way with cleaner code:
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.
rhettinger commentedon Jul 20, 2014
This isn't a Java-only concept. It is widely available. Here's a sample:
c++
"thread_group provides for a collection of threads that are related in some fashion."
http://www.boost.org/doc/libs/1_35_0/doc/html/thread/thread_management.html#thread.thread_management.threadgroup
perl
"Thread::Pool - group of threads for performing similar jobs"
http://search.cpan.org/dist/Thread-Pool/lib/Thread/Pool.pm
haskell
"This module extends Control.Concurrent.Thread with the ability to wait for a group of threads to terminate."
http://hackage.haskell.org/package/threads-0.5.0.2/docs/Control-Concurrent-Thread-Group.html
ruby
"ThreadGroup provides a means of keeping track of a number of threads as a group."
http://www.ruby-doc.org/core-2.1.2/ThreadGroup.html
Tinche commentedon Jul 20, 2014
For your examples, my first instinct would be to use a thread pool executor. It's a nice high level API and can already do the aggregate join.
PCManticore commentedon Jul 20, 2014
This seems indeed like a weaker version of ThreadPoolExecutor. Here's how your example looks with it, not very different and still easy to understand and grasp:
3 lines without imports and the initialisation of the pool.
neologix commentedon Jul 21, 2014
Indeed, the examples posted don't make much sense: thread/process
pools are the way to go.
iritkatriel commentedon Mar 21, 2022
And now we have TaskGroups in asyncio as well.
I'm closing this as it seems to have been abandoned. Feel free to reopen if this is still needed.