-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
threading.Thread: use target name if the name parameter is omitted #85999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
When debugging race conditions in a multithreaded application with many threads, it's hard to debug when threads have generic names like "Thread-3". I propose to use the target name in threading.Thread constructor if the name parameter is omitted. See for example bpo-41739 with "Dangling thread: <Thread(Thread-3, started daemon 4396088817936)>": the "Thread-3" name is not helpful. I suspect that the bug comes from threading.Thread(target=remove_loop, args=(fn, del_count)): with my proposed change, the thread would be called "target=remove_loop", which is more helpful than "Thread". Fall back on _newname() as usual if target.__name__ attribute does not exist. Attached PR implements this idea. |
And what if run different threads with the same target or with different targets with the same name? Would not "Thread-3" be more useful in this case? for i in range(10):
Thread(target=print, args=(i,)).start()
for i in range(10):
def doit(i=i):
print(i)
Thread(target=doit).start() |
If multiple Thread objects using the same target (or different targets with the same name), they all get the same name using my PR 22357.
Well, that's an open question. In my experience, "Thread" name is pretty useless. What if I modify my PR to add "-{counter}" (ex: "func-3" for target.__name__="func") to the default name? Reuse _counter(). Pseudo-code: self._name = str(name)
try:
base_name = target.__name__
except AttributeError:
base_name = "Thread"
if not self._name:
self._name = "{base_name)-{_counter()}" |
See also bpo-15500 "Python should support exporting thread names to the OS". |
Having the target in the thread name definitely seems like a good idea and would help ease debugging, not just for our tests but when printing thread objects in general. I would agree with the suggestion of placing the counter in there for when multiple threads get spawned with the same target or maybe even using names like: Thread-1 (doit) might be better just for people who are familiar with them. |
I rewrote my PR to generate names like "Thread-3 (func)", rather than just "func". So if two target functions have the same name, or if two threads use the same target, it remains possible to distinguish the two threads. |
Ideally, I would prefer separate counters for different names, and omitting a number for the first thread with unique name: doit But it is not feasible. It would require supporting a cache which can grow with every new thread and non-trivial code to avoid race conditions. So I am fine with Ammar's idea. |
IMO if you want to go at the level of details, I suggest you to generate yourself thread names: threads = [threading.Thread(name=f"MyThread-{i}") for i in range(1, 6)] Maintaining a list of thread names sounds overkill to me. It would be quite complicated and would increase the memory footprint, for little benefit. |
I merged my change with "Thread-1 (func)" format: add the target name, but keep "Thread-3" to distinguish two different threads with the same target name. |
Cool, my threading change works as expected! The name of the target function was logged in bpo-41739 issue. https://buildbot.python.org/all/#/builders/509/builds/172 0:00:28 load avg: 3.58 [ 36/424/1] test_logging failed (env changed) See "<Thread(Thread-4 (removeTarget), started daemon 4396862667024)>": the two leaked threads are running the removeTarget() function which come from MemoryHandlerTest.test_race_between_set_target_and_flush(). By the way, Serhiy was right about the name of having an unique repr() even if the target is the same, since it's the case here ;-) Well "4396862667024" is different than "4396595259664", but it's more convinient to have short numbers like "Thread-4" and "Thread-11". |
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:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: