Tachyon /Users/simon/.local/share/uv/python/cpython-3.15.0-macos-aarch64-none/lib/python3.15/threading.py
15
Self Samples
29107
Cumulative
6
Lines Hit
100.00%
% of Total
12
Max Self
14546
Max Total
Intensity:
Cold Hot
Self Time
Total Time
Show All
Hot Only
Heat
Specialization
Line
Self
Total
Code
1
"""Thread module emulating a subset of Java's threading model."""
2
3
import os as _os
4
import sys as _sys
5
import _thread
6
import _contextvars
7
8
from time import monotonic as _time
9
from _weakrefset import WeakSet
10
from itertools import count as _count
11
try:
12
from _collections import deque as _deque
13
except ImportError:
14
from collections import deque as _deque
15
16
# Note regarding PEP 8 compliant names
17
# This threading model was originally inspired by Java, and inherited
18
# the convention of camelCase function and method names from that
19
# language. Those original names are not in any imminent danger of
20
# being deprecated (even for Py3k),so this module provides them as an
21
# alias for the PEP 8 compliant names
22
# Note that using the new PEP 8 compliant names facilitates substitution
23
# with the multiprocessing module, which doesn't provide the old
24
# Java inspired names.
25
26
__all__ = ['get_ident', 'active_count', 'Condition', 'current_thread',
27
'enumerate', 'main_thread', 'TIMEOUT_MAX',
28
'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread',
29
'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError',
30
'setprofile', 'settrace', 'local', 'stack_size',
31
'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile',
32
'serialize_iterator', 'synchronized_iterator', 'concurrent_tee',
33
'setprofile_all_threads','settrace_all_threads']
34
35
# Rename some stuff so "from threading import *" is safe
36
_start_joinable_thread = _thread.start_joinable_thread
37
_daemon_threads_allowed = _thread.daemon_threads_allowed
38
_allocate_lock = _thread.allocate_lock
39
_LockType = _thread.LockType
40
_thread_shutdown = _thread._shutdown
41
_make_thread_handle = _thread._make_thread_handle
42
_ThreadHandle = _thread._ThreadHandle
43
get_ident = _thread.get_ident
44
_get_main_thread_ident = _thread._get_main_thread_ident
45
_is_main_interpreter = _thread._is_main_interpreter
46
try:
47
get_native_id = _thread.get_native_id
48
_HAVE_THREAD_NATIVE_ID = True
49
__all__.append('get_native_id')
50
except AttributeError:
51
_HAVE_THREAD_NATIVE_ID = False
52
try:
53
_set_name = _thread.set_name
54
except AttributeError:
55
_set_name = None
56
ThreadError = _thread.error
57
try:
58
_CRLock = _thread.RLock
59
except AttributeError:
60
_CRLock = None
61
TIMEOUT_MAX = _thread.TIMEOUT_MAX
62
del _thread
63
64
# get thread-local implementation, either from the thread
65
# module, or from the python fallback
66
67
try:
68
from _thread import _local as local
69
except ImportError:
70
from _threading_local import local
71
72
# Support for profile and trace hooks
73
74
_profile_hook = None
75
_trace_hook = None
76
77
def setprofile(func):
78
"""Set a profile function for all threads started from the threading module.
79
80
The func will be passed to sys.setprofile() for each thread, before its
81
run() method is called.
82
"""
83
global _profile_hook
84
_profile_hook = func
85
86
def setprofile_all_threads(func):
87
"""Set a profile function for all threads started from the threading module
88
and all Python threads that are currently executing.
89
90
The func will be passed to sys.setprofile() for each thread, before its
91
run() method is called.
92
"""
93
setprofile(func)
94
_sys._setprofileallthreads(func)
95
96
def getprofile():
97
"""Get the profiler function as set by threading.setprofile()."""
98
return _profile_hook
99
100
def settrace(func):
101
"""Set a trace function for all threads started from the threading module.
102
103
The func will be passed to sys.settrace() for each thread, before its run()
104
method is called.
105
"""
106
global _trace_hook
107
_trace_hook = func
108
109
def settrace_all_threads(func):
110
"""Set a trace function for all threads started from the threading module
111
and all Python threads that are currently executing.
112
113
The func will be passed to sys.settrace() for each thread, before its run()
114
method is called.
115
"""
116
settrace(func)
117
_sys._settraceallthreads(func)
118
119
def gettrace():
120
"""Get the trace function as set by threading.settrace()."""
121
return _trace_hook
122
123
# Synchronization classes
124
125
Lock = _LockType
126
127
def RLock():
128
"""Factory function that returns a new reentrant lock.
129
130
A reentrant lock must be released by the thread that acquired it. Once a
131
thread has acquired a reentrant lock, the same thread may acquire it again
132
without blocking; the thread must release it once for each time it has
133
acquired it.
134
135
"""
136
if _CRLock is None:
137
return _PyRLock()
138
return _CRLock()
139
140
class _RLock:
141
"""This class implements reentrant lock objects.
142
143
A reentrant lock must be released by the thread that acquired it. Once a
144
thread has acquired a reentrant lock, the same thread may acquire it
145
again without blocking; the thread must release it once for each time it
146
has acquired it.
147
148
"""
149
150
def __init__(self):
151
self._block = _allocate_lock()
152
self._owner = None
153
self._count = 0
154
155
def __repr__(self):
156
owner = self._owner
157
try:
158
owner = _active[owner].name
159
except KeyError:
160
pass
161
return "<%s %s.%s object owner=%r count=%d at %s>" % (
162
"locked" if self.locked() else "unlocked",
163
self.__class__.__module__,
164
self.__class__.__qualname__,
165
owner,
166
self._count,
167
hex(id(self))
168
)
169
170
def _at_fork_reinit(self):
171
self._block._at_fork_reinit()
172
self._owner = None
173
self._count = 0
174
175
def acquire(self, blocking=True, timeout=-1):
176
"""Acquire a lock, blocking or non-blocking.
177
178
When invoked without arguments: if this thread already owns the lock,
179
increment the recursion level by one, and return immediately. Otherwise,
180
if another thread owns the lock, block until the lock is unlocked. Once
181
the lock is unlocked (not owned by any thread), then grab ownership, set
182
the recursion level to one, and return. If more than one thread is
183
blocked waiting until the lock is unlocked, only one at a time will be
184
able to grab ownership of the lock. There is no return value in this
185
case.
186
187
When invoked with the blocking argument set to true, do the same thing
188
as when called without arguments, and return true.
189
190
When invoked with the blocking argument set to false, do not block. If a
191
call without an argument would block, return false immediately;
192
otherwise, do the same thing as when called without arguments, and
193
return true.
194
195
When invoked with the floating-point timeout argument set to a positive
196
value, block for at most the number of seconds specified by timeout
197
and as long as the lock cannot be acquired. Return true if the lock has
198
been acquired, false if the timeout has elapsed.
199
200
"""
201
me = get_ident()
202
if self._owner == me:
203
self._count += 1
204
return 1
205
rc = self._block.acquire(blocking, timeout)
206
if rc:
207
self._owner = me
208
self._count = 1
209
return rc
210
211
__enter__ = acquire
212
213
def release(self):
214
"""Release a lock, decrementing the recursion level.
215
216
If after the decrement it is zero, reset the lock to unlocked (not owned
217
by any thread), and if any other threads are blocked waiting for the
218
lock to become unlocked, allow exactly one of them to proceed. If after
219
the decrement the recursion level is still nonzero, the lock remains
220
locked and owned by the calling thread.
221
222
Only call this method when the calling thread owns the lock. A
223
RuntimeError is raised if this method is called when the lock is
224
unlocked.
225
226
There is no return value.
227
228
"""
229
if self._owner != get_ident():
230
raise RuntimeError("cannot release un-acquired lock")
231
self._count = count = self._count - 1
232
if not count:
233
self._owner = None
234
self._block.release()
235
236
def __exit__(self, t, v, tb):
237
self.release()
238
239
def locked(self):
240
"""Return whether this object is locked."""
241
return self._block.locked()
242
243
# Internal methods used by condition variables
244
245
def _acquire_restore(self, state):
246
self._block.acquire()
247
self._count, self._owner = state
248
249
def _release_save(self):
250
if self._count == 0:
251
raise RuntimeError("cannot release un-acquired lock")
252
count = self._count
253
self._count = 0
254
owner = self._owner
255
self._owner = None
256
self._block.release()
257
return (count, owner)
258
259
def _is_owned(self):
260
return self._owner == get_ident()
261
262
# Internal method used for reentrancy checks
263
264
def _recursion_count(self):
265
if self._owner != get_ident():
266
return 0
267
return self._count
268
269
_PyRLock = _RLock
270
271
272
class Condition:
273
"""Class that implements a condition variable.
274
275
A condition variable allows one or more threads to wait until they are
276
notified by another thread.
277
278
If the lock argument is given and not None, it must be a Lock or RLock
279
object, and it is used as the underlying lock. Otherwise, a new RLock object
280
is created and used as the underlying lock.
281
282
"""
283
284
def __init__(self, lock=None):
285
if lock is None:
286
lock = RLock()
287
self._lock = lock
288
# Export the lock's acquire(), release(), and locked() methods
289
self.acquire = lock.acquire
290
self.release = lock.release
291
self.locked = lock.locked
292
# If the lock defines _release_save() and/or _acquire_restore(),
293
# these override the default implementations (which just call
294
# release() and acquire() on the lock). Ditto for _is_owned().
295
if hasattr(lock, '_release_save'):
296
self._release_save = lock._release_save
297
if hasattr(lock, '_acquire_restore'):
298
self._acquire_restore = lock._acquire_restore
299
if hasattr(lock, '_is_owned'):
300
self._is_owned = lock._is_owned
301
self._waiters = _deque()
302
303
def _at_fork_reinit(self):
304
self._lock._at_fork_reinit()
305
self._waiters.clear()
306
307
def __enter__(self):
308
return self._lock.__enter__()
309
310
def __exit__(self, *args):
311
1
1
return self._lock.__exit__(*args)
312
313
def __repr__(self):
314
return "<Condition(%s, %d)>" % (self._lock, len(self._waiters))
315
316
def _release_save(self):
317
self._lock.release() # No state to save
318
319
def _acquire_restore(self, x):
320
self._lock.acquire() # Ignore saved state
321
322
def _is_owned(self):
323
# Return True if lock is owned by current_thread.
324
# This method is called only if _lock doesn't have _is_owned().
325
if self._lock.acquire(False):
326
self._lock.release()
327
return False
328
else:
329
return True
330
331
def wait(self, timeout=None):
332
"""Wait until notified or until a timeout occurs.
333
334
If the calling thread has not acquired the lock when this method is
335
called, a RuntimeError is raised.
336
337
This method releases the underlying lock, and then blocks until it is
338
awakened by a notify() or notify_all() call for the same condition
339
variable in another thread, or until the optional timeout occurs. Once
340
awakened or timed out, it re-acquires the lock and returns.
341
342
When the timeout argument is present and not None, it should be a
343
floating-point number specifying a timeout for the operation in seconds
344
(or fractions thereof).
345
346
When the underlying lock is an RLock, it is not released using its
347
release() method, since this may not actually unlock the lock when it
348
was acquired multiple times recursively. Instead, an internal interface
349
of the RLock class is used, which really unlocks it even when it has
350
been recursively acquired several times. Another internal interface is
351
then used to restore the recursion level when the lock is reacquired.
352
353
"""
354
if not self._is_owned():
355
raise RuntimeError("cannot wait on un-acquired lock")
356
waiter = _allocate_lock()
357
waiter.acquire()
358
1
1
self._waiters.append(waiter)
359
saved_state = self._release_save()
360
gotit = False
361
try: # restore state no matter what (e.g., KeyboardInterrupt)
362
if timeout is None:
363
12
12
waiter.acquire()
364
gotit = True
365
else:
366
if timeout > 0:
367
gotit = waiter.acquire(True, timeout)
368
else:
369
gotit = waiter.acquire(False)
370
return gotit
371
finally:
372
1
1
self._acquire_restore(saved_state)
373
if not gotit:
374
try:
375
self._waiters.remove(waiter)
376
except ValueError:
377
pass
378
379
def wait_for(self, predicate, timeout=None):
380
"""Wait until a condition evaluates to True.
381
382
predicate should be a callable which result will be interpreted as a
383
boolean value. A timeout may be provided giving the maximum time to
384
wait.
385
386
"""
387
endtime = None
388
waittime = timeout
389
result = predicate()
390
while not result:
391
if waittime is not None:
392
if endtime is None:
393
endtime = _time() + waittime
394
else:
395
waittime = endtime - _time()
396
if waittime <= 0:
397
break
398
self.wait(waittime)
399
result = predicate()
400
return result
401
402
def notify(self, n=1):
403
"""Wake up one or more threads waiting on this condition, if any.
404
405
If the calling thread has not acquired the lock when this method is
406
called, a RuntimeError is raised.
407
408
This method wakes up at most n of the threads waiting for the condition
409
variable; it is a no-op if no threads are waiting.
410
411
"""
412
if not self._is_owned():
413
raise RuntimeError("cannot notify on un-acquired lock")
414
waiters = self._waiters
415
while waiters and n > 0:
416
waiter = waiters[0]
417
try:
418
waiter.release()
419
except RuntimeError:
420
# gh-92530: The previous call of notify() released the lock,
421
# but was interrupted before removing it from the queue.
422
# It can happen if a signal handler raises an exception,
423
# like CTRL+C which raises KeyboardInterrupt.
424
pass
425
else:
426
n -= 1
427
try:
428
waiters.remove(waiter)
429
except ValueError:
430
pass
431
432
def notify_all(self):
433
"""Wake up all threads waiting on this condition.
434
435
If the calling thread has not acquired the lock when this method
436
is called, a RuntimeError is raised.
437
438
"""
439
self.notify(len(self._waiters))
440
441
def notifyAll(self):
442
"""Wake up all threads waiting on this condition.
443
444
This method is deprecated, use notify_all() instead.
445
446
"""
447
import warnings
448
warnings.warn('notifyAll() is deprecated, use notify_all() instead',
449
DeprecationWarning, stacklevel=2)
450
self.notify_all()
451
452
453
class Semaphore:
454
"""This class implements semaphore objects.
455
456
Semaphores manage a counter representing the number of release() calls minus
457
the number of acquire() calls, plus an initial value. The acquire() method
458
blocks if necessary until it can return without making the counter
459
negative. If not given, value defaults to 1.
460
461
"""
462
463
# After Tim Peters' semaphore class, but not quite the same (no maximum)
464
465
def __init__(self, value=1):
466
if value < 0:
467
raise ValueError("semaphore initial value must be >= 0")
468
self._cond = Condition(Lock())
469
self._value = value
470
471
def __repr__(self):
472
cls = self.__class__
473
return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:"
474
f" value={self._value}>")
475
476
def acquire(self, blocking=True, timeout=None):
477
"""Acquire a semaphore, decrementing the internal counter by one.
478
479
When invoked without arguments: if the internal counter is larger than
480
zero on entry, decrement it by one and return immediately. If it is zero
481
on entry, block, waiting until some other thread has called release() to
482
make it larger than zero. This is done with proper interlocking so that
483
if multiple acquire() calls are blocked, release() will wake exactly one
484
of them up. The implementation may pick one at random, so the order in
485
which blocked threads are awakened should not be relied on. There is no
486
return value in this case.
487
488
When invoked with blocking set to true, do the same thing as when called
489
without arguments, and return true.
490
491
When invoked with blocking set to false, do not block. If a call without
492
an argument would block, return false immediately; otherwise, do the
493
same thing as when called without arguments, and return true.
494
495
When invoked with a timeout other than None, it will block for at
496
most timeout seconds. If acquire does not complete successfully in
497
that interval, return false. Return true otherwise.
498
499
"""
500
if not blocking and timeout is not None:
501
raise ValueError("can't specify timeout for non-blocking acquire")
502
rc = False
503
endtime = None
504
with self._cond:
505
while self._value == 0:
506
if not blocking:
507
break
508
if timeout is not None:
509
if endtime is None:
510
endtime = _time() + timeout
511
else:
512
timeout = endtime - _time()
513
if timeout <= 0:
514
break
515
self._cond.wait(timeout)
516
else:
517
self._value -= 1
518
rc = True
519
return rc
520
521
__enter__ = acquire
522
523
def release(self, n=1):
524
"""Release a semaphore, incrementing the internal counter by one or more.
525
526
When the counter is zero on entry and another thread is waiting for it
527
to become larger than zero again, wake up that thread.
528
529
"""
530
if n < 1:
531
raise ValueError('n must be one or more')
532
with self._cond:
533
self._value += n
534
self._cond.notify(n)
535
536
def __exit__(self, t, v, tb):
537
self.release()
538
539
540
class BoundedSemaphore(Semaphore):
541
"""Implements a bounded semaphore.
542
543
A bounded semaphore checks to make sure its current value doesn't exceed its
544
initial value. If it does, ValueError is raised. In most situations
545
semaphores are used to guard resources with limited capacity.
546
547
If the semaphore is released too many times it's a sign of a bug. If not
548
given, value defaults to 1.
549
550
Like regular semaphores, bounded semaphores manage a counter representing
551
the number of release() calls minus the number of acquire() calls, plus an
552
initial value. The acquire() method blocks if necessary until it can return
553
without making the counter negative. If not given, value defaults to 1.
554
555
"""
556
557
def __init__(self, value=1):
558
super().__init__(value)
559
self._initial_value = value
560
561
def __repr__(self):
562
cls = self.__class__
563
return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:"
564
f" value={self._value}/{self._initial_value}>")
565
566
def release(self, n=1):
567
"""Release a semaphore, incrementing the internal counter by one or more.
568
569
When the counter is zero on entry and another thread is waiting for it
570
to become larger than zero again, wake up that thread.
571
572
If the number of releases exceeds the number of acquires,
573
raise a ValueError.
574
575
"""
576
if n < 1:
577
raise ValueError('n must be one or more')
578
with self._cond:
579
if self._value + n > self._initial_value:
580
raise ValueError("Semaphore released too many times")
581
self._value += n
582
self._cond.notify(n)
583
584
585
class Event:
586
"""Class implementing event objects.
587
588
Events manage a flag that can be set to true with the set() method and reset
589
to false with the clear() method. The wait() method blocks until the flag is
590
true. The flag is initially false.
591
592
"""
593
594
# After Tim Peters' event class (without is_posted())
595
596
def __init__(self):
597
self._cond = Condition(Lock())
598
self._flag = False
599
600
def __repr__(self):
601
cls = self.__class__
602
status = 'set' if self._flag else 'unset'
603
return f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}: {status}>"
604
605
def _at_fork_reinit(self):
606
# Private method called by Thread._after_fork()
607
self._cond._at_fork_reinit()
608
609
def is_set(self):
610
"""Return true if and only if the internal flag is true."""
611
return self._flag
612
613
def isSet(self):
614
"""Return true if and only if the internal flag is true.
615
616
This method is deprecated, use is_set() instead.
617
618
"""
619
import warnings
620
warnings.warn('isSet() is deprecated, use is_set() instead',
621
DeprecationWarning, stacklevel=2)
622
return self.is_set()
623
624
def set(self):
625
"""Set the internal flag to true.
626
627
All threads waiting for it to become true are awakened. Threads
628
that call wait() once the flag is true will not block at all.
629
630
"""
631
with self._cond:
632
self._flag = True
633
self._cond.notify_all()
634
635
def clear(self):
636
"""Reset the internal flag to false.
637
638
Subsequently, threads calling wait() will block until set() is called to
639
set the internal flag to true again.
640
641
"""
642
with self._cond:
643
self._flag = False
644
645
def wait(self, timeout=None):
646
"""Block until the internal flag is true.
647
648
If the internal flag is true on entry, return immediately. Otherwise,
649
block until another thread calls set() to set the flag to true, or until
650
the optional timeout occurs.
651
652
When the timeout argument is present and not None, it should be a
653
floating-point number specifying a timeout for the operation in seconds
654
(or fractions thereof).
655
656
This method returns the internal flag on exit, so it will always return
657
``True`` except if a timeout is given and the operation times out, when
658
it will return ``False``.
659
660
"""
661
with self._cond:
662
signaled = self._flag
663
if not signaled:
664
signaled = self._cond.wait(timeout)
665
return signaled
666
667
668
# A barrier class. Inspired in part by the pthread_barrier_* api and
669
# the CyclicBarrier class from Java. See
670
# http://sourceware.org/pthreads-win32/manual/pthread_barrier_init.html and
671
# http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/
672
# CyclicBarrier.html
673
# for information.
674
# We maintain two main states, 'filling' and 'draining' enabling the barrier
675
# to be cyclic. Threads are not allowed into it until it has fully drained
676
# since the previous cycle. In addition, a 'resetting' state exists which is
677
# similar to 'draining' except that threads leave with a BrokenBarrierError,
678
# and a 'broken' state in which all threads get the exception.
679
class Barrier:
680
"""Implements a Barrier.
681
682
Useful for synchronizing a fixed number of threads at known synchronization
683
points. Threads block on 'wait()' and are simultaneously awoken once they
684
have all made that call.
685
686
"""
687
688
def __init__(self, parties, action=None, timeout=None):
689
"""Create a barrier, initialised to 'parties' threads.
690
691
'action' is a callable which, when supplied, will be called by one of
692
the threads after they have all entered the barrier and just prior to
693
releasing them all. If a 'timeout' is provided, it is used as the
694
default for all subsequent 'wait()' calls.
695
696
"""
697
if parties < 1:
698
raise ValueError("parties must be >= 1")
699
self._cond = Condition(Lock())
700
self._action = action
701
self._timeout = timeout
702
self._parties = parties
703
self._state = 0 # 0 filling, 1 draining, -1 resetting, -2 broken
704
self._count = 0
705
706
def __repr__(self):
707
cls = self.__class__
708
if self.broken:
709
return f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}: broken>"
710
return (f"<{cls.__module__}.{cls.__qualname__} at {id(self):#x}:"
711
f" waiters={self.n_waiting}/{self.parties}>")
712
713
def wait(self, timeout=None):
714
"""Wait for the barrier.
715
716
When the specified number of threads have started waiting, they are all
717
simultaneously awoken. If an 'action' was provided for the barrier, one
718
of the threads will have executed that callback prior to returning.
719
Returns an individual index number from 0 to 'parties-1'.
720
721
"""
722
if timeout is None:
723
timeout = self._timeout
724
with self._cond:
725
self._enter() # Block while the barrier drains.
726
index = self._count
727
self._count += 1
728
try:
729
if index + 1 == self._parties:
730
# We release the barrier
731
self._release()
732
else:
733
# We wait until someone releases us
734
self._wait(timeout)
735
return index
736
finally:
737
self._count -= 1
738
# Wake up any threads waiting for barrier to drain.
739
self._exit()
740
741
# Block until the barrier is ready for us, or raise an exception
742
# if it is broken.
743
def _enter(self):
744
while self._state in (-1, 1):
745
# It is draining or resetting, wait until done
746
self._cond.wait()
747
#see if the barrier is in a broken state
748
if self._state < 0:
749
raise BrokenBarrierError
750
assert self._state == 0
751
752
# Optionally run the 'action' and release the threads waiting
753
# in the barrier.
754
def _release(self):
755
try:
756
if self._action:
757
self._action()
758
# enter draining state
759
self._state = 1
760
self._cond.notify_all()
761
except:
762
#an exception during the _action handler. Break and reraise
763
self._break()
764
raise
765
766
# Wait in the barrier until we are released. Raise an exception
767
# if the barrier is reset or broken.
768
def _wait(self, timeout):
769
if not self._cond.wait_for(lambda : self._state != 0, timeout):
770
#timed out. Break the barrier
771
self._break()
772
raise BrokenBarrierError
773
if self._state < 0:
774
raise BrokenBarrierError
775
assert self._state == 1
776
777
# If we are the last thread to exit the barrier, signal any threads
778
# waiting for the barrier to drain.
779
def _exit(self):
780
if self._count == 0:
781
if self._state in (-1, 1):
782
#resetting or draining
783
self._state = 0
784
self._cond.notify_all()
785
786
def reset(self):
787
"""Reset the barrier to the initial state.
788
789
Any threads currently waiting will get the BrokenBarrier exception
790
raised.
791
792
"""
793
with self._cond:
794
if self._count > 0:
795
if self._state == 0:
796
#reset the barrier, waking up threads
797
self._state = -1
798
elif self._state == -2:
799
#was broken, set it to reset state
800
#which clears when the last thread exits
801
self._state = -1
802
else:
803
self._state = 0
804
self._cond.notify_all()
805
806
def abort(self):
807
"""Place the barrier into a 'broken' state.
808
809
Useful in case of error. Any currently waiting threads and threads
810
attempting to 'wait()' will have BrokenBarrierError raised.
811
812
"""
813
with self._cond:
814
self._break()
815
816
def _break(self):
817
# An internal error was detected. The barrier is set to
818
# a broken state all parties awakened.
819
self._state = -2
820
self._cond.notify_all()
821
822
@property
823
def parties(self):
824
"""Return the number of threads required to trip the barrier."""
825
return self._parties
826
827
@property
828
def n_waiting(self):
829
"""Return the number of threads currently waiting at the barrier."""
830
# We don't need synchronization here since this is an ephemeral result
831
# anyway. It returns the correct value in the steady state.
832
if self._state == 0:
833
return self._count
834
return 0
835
836
@property
837
def broken(self):
838
"""Return True if the barrier is in a broken state."""
839
return self._state == -2
840
841
# exception raised by the Barrier class
842
class BrokenBarrierError(RuntimeError):
843
pass
844
845
846
## Synchronization tools for iterators #####################
847
848
class serialize_iterator:
849
"""Wrap a non-concurrent iterator with a lock to enforce sequential access.
850
851
Applies a non-reentrant lock around calls to __next__. If the
852
wrapped iterator also defines send(), throw(), or close(), those
853
calls are serialized as well.
854
855
Allows iterator and generator instances to be shared by multiple consumer
856
threads.
857
858
For example, itertools.count does not make thread-safe instances,
859
but that is easily fixed with:
860
861
atomic_counter = serialize_iterator(itertools.count())
862
863
"""
864
865
__slots__ = ('_iterator', '_lock')
866
867
def __init__(self, iterable):
868
self._iterator = iter(iterable)
869
self._lock = Lock()
870
871
def __iter__(self):
872
return self
873
874
def __next__(self):
875
with self._lock:
876
return next(self._iterator)
877
878
def send(self, value, /):
879
"""Send a value to a generator.
880
881
Raises AttributeError if not a generator.
882
"""
883
with self._lock:
884
return self._iterator.send(value)
885
886
def throw(self, *args):
887
"""Call throw() on a generator.
888
889
Raises AttributeError if not a generator.
890
"""
891
with self._lock:
892
return self._iterator.throw(*args)
893
894
def close(self):
895
"""Call close() on a generator.
896
897
Raises AttributeError if not a generator.
898
"""
899
with self._lock:
900
return self._iterator.close()
901
902
903
def synchronized_iterator(func):
904
"""Wrap an iterator-returning callable to make its iterators thread-safe.
905
906
Existing itertools and more-itertools can be wrapped so that their
907
iterator instances are serialized.
908
909
For example, itertools.count does not make thread-safe instances,
910
but that is easily fixed with:
911
912
atomic_counter = synchronized_iterator(itertools.count)
913
914
Can also be used as a decorator for generator function definitions
915
so that the generator instances are serialized::
916
917
import time
918
919
@synchronized_iterator
920
def enumerate_and_timestamp(iterable):
921
for count, value in enumerate(iterable):
922
yield count, time.time_ns(), value
923
924
"""
925
926
from functools import wraps
927
928
@wraps(func)
929
def inner(*args, **kwargs):
930
iterator = func(*args, **kwargs)
931
return serialize_iterator(iterator)
932
933
return inner
934
935
936
def concurrent_tee(iterable, n=2):
937
"""Variant of itertools.tee() but with guaranteed threading semantics.
938
939
Takes a non-threadsafe iterator as an input and creates concurrent
940
tee objects for other threads to have reliable independent copies of
941
the data stream.
942
943
The new iterators are only thread-safe if consumed within a single thread.
944
To share just one of the new iterators across multiple threads, wrap it
945
with threading.serialize_iterator().
946
"""
947
948
if n < 0:
949
raise ValueError("n must be a non-negative integer")
950
if n == 0:
951
return ()
952
iterator = _concurrent_tee(iterable)
953
result = [iterator]
954
for _ in range(n - 1):
955
result.append(_concurrent_tee(iterator))
956
return tuple(result)
957
958
959
class _concurrent_tee:
960
__slots__ = ('iterator', 'link', 'lock')
961
962
def __init__(self, iterable):
963
if isinstance(iterable, _concurrent_tee):
964
self.iterator = iterable.iterator
965
self.link = iterable.link
966
self.lock = iterable.lock
967
else:
968
self.iterator = iter(iterable)
969
self.link = [None, None]
970
self.lock = Lock()
971
972
def __iter__(self):
973
return self
974
975
def __next__(self):
976
link = self.link
977
if link[1] is None:
978
with self.lock:
979
if link[1] is None:
980
link[0] = next(self.iterator)
981
link[1] = [None, None]
982
value, self.link = link
983
return value
984
985
############################################################
986
987
988
# Helper to generate new thread names
989
_counter = _count(1).__next__
990
def _newname(name_template):
991
return name_template % _counter()
992
993
# Active thread administration.
994
#
995
# bpo-44422: Use a reentrant lock to allow reentrant calls to functions like
996
# threading.enumerate().
997
_active_limbo_lock = RLock()
998
_active = {} # maps thread id to Thread object
999
_limbo = {}
1000
_dangling = WeakSet()
1001
1002
1003
# Main class for threads
1004
1005
class Thread:
1006
"""A class that represents a thread of control.
1007
1008
This class can be safely subclassed in a limited fashion. There are two ways
1009
to specify the activity: by passing a callable object to the constructor, or
1010
by overriding the run() method in a subclass.
1011
1012
"""
1013
1014
_initialized = False
1015
1016
def __init__(self, group=None, target=None, name=None,
1017
args=(), kwargs=None, *, daemon=None, context=None):
1018
"""This constructor should always be called with keyword arguments. Arguments are:
1019
1020
*group* should be None; reserved for future extension when a ThreadGroup
1021
class is implemented.
1022
1023
*target* is the callable object to be invoked by the run()
1024
method. Defaults to None, meaning nothing is called.
1025
1026
*name* is the thread name. By default, a unique name is constructed of
1027
the form "Thread-N" where N is a small decimal number.
1028
1029
*args* is a list or tuple of arguments for the target invocation. Defaults to ().
1030
1031
*kwargs* is a dictionary of keyword arguments for the target
1032
invocation. Defaults to {}.
1033
1034
*context* is the contextvars.Context value to use for the thread.
1035
The default value is None, which means to check
1036
sys.flags.thread_inherit_context. If that flag is true, use a copy
1037
of the context of the caller. If false, use an empty context. To
1038
explicitly start with an empty context, pass a new instance of
1039
contextvars.Context(). To explicitly start with a copy of the current
1040
context, pass the value from contextvars.copy_context().
1041
1042
If a subclass overrides the constructor, it must make sure to invoke
1043
the base class constructor (Thread.__init__()) before doing anything
1044
else to the thread.
1045
1046
"""
1047
assert group is None, "group argument must be None for now"
1048
if kwargs is None:
1049
kwargs = {}
1050
if name:
1051
name = str(name)
1052
else:
1053
name = _newname("Thread-%d")
1054
if target is not None:
1055
try:
1056
target_name = target.__name__
1057
name += f" ({target_name})"
1058
except AttributeError:
1059
pass
1060
1061
self._target = target
1062
self._name = name
1063
self._args = args
1064
self._kwargs = kwargs
1065
if daemon is not None:
1066
if daemon and not _daemon_threads_allowed():
1067
raise RuntimeError('daemon threads are disabled in this (sub)interpreter')
1068
self._daemonic = daemon
1069
else:
1070
self._daemonic = current_thread().daemon
1071
self._context = context
1072
self._ident = None
1073
if _HAVE_THREAD_NATIVE_ID:
1074
self._native_id = None
1075
self._os_thread_handle = _ThreadHandle()
1076
self._started = Event()
1077
self._initialized = True
1078
# Copy of sys.stderr used by self._invoke_excepthook()
1079
self._stderr = _sys.stderr
1080
self._invoke_excepthook = _make_invoke_excepthook()
1081
# For debugging and _after_fork()
1082
_dangling.add(self)
1083
1084
def _after_fork(self, new_ident=None):
1085
# Private! Called by threading._after_fork().
1086
self._started._at_fork_reinit()
1087
if new_ident is not None:
1088
# This thread is alive.
1089
self._ident = new_ident
1090
assert self._os_thread_handle.ident == new_ident
1091
if _HAVE_THREAD_NATIVE_ID:
1092
self._set_native_id()
1093
else:
1094
# Otherwise, the thread is dead, Jim. _PyThread_AfterFork()
1095
# already marked our handle done.
1096
pass
1097
1098
def __repr__(self):
1099
assert self._initialized, "Thread.__init__() was not called"
1100
status = "initial"
1101
if self._started.is_set():
1102
status = "started"
1103
if self._os_thread_handle.is_done():
1104
status = "stopped"
1105
if self._daemonic:
1106
status += " daemon"
1107
if self._ident is not None:
1108
status += " %s" % self._ident
1109
return "<%s(%s, %s)>" % (self.__class__.__name__, self._name, status)
1110
1111
def start(self):
1112
"""Start the thread's activity.
1113
1114
It must be called at most once per thread object. It arranges for the
1115
object's run() method to be invoked in a separate thread of control.
1116
1117
This method will raise a RuntimeError if called more than once on the
1118
same thread object.
1119
1120
"""
1121
if not self._initialized:
1122
raise RuntimeError("thread.__init__() not called")
1123
1124
if self._started.is_set():
1125
raise RuntimeError("threads can only be started once")
1126
1127
with _active_limbo_lock:
1128
_limbo[self] = self
1129
1130
if self._context is None:
1131
# No context provided
1132
if _sys.flags.thread_inherit_context:
1133
# start with a copy of the context of the caller
1134
self._context = _contextvars.copy_context()
1135
else:
1136
# start with an empty context
1137
self._context = _contextvars.Context()
1138
1139
try:
1140
# Start joinable thread
1141
_start_joinable_thread(self._bootstrap, handle=self._os_thread_handle,
1142
daemon=self.daemon)
1143
except Exception:
1144
with _active_limbo_lock:
1145
del _limbo[self]
1146
raise
1147
self._started.wait() # Will set ident and native_id
1148
1149
def run(self):
1150
"""Method representing the thread's activity.
1151
1152
You may override this method in a subclass. The standard run() method
1153
invokes the callable object passed to the object's constructor as the
1154
target argument, if any, with sequential and keyword arguments taken
1155
from the args and kwargs arguments, respectively.
1156
1157
"""
1158
try:
1159
if self._target is not None:
1160
self._target(*self._args, **self._kwargs)
1161
finally:
1162
# Avoid a refcycle if the thread is running a function with
1163
# an argument that has a member that points to the thread.
1164
del self._target, self._args, self._kwargs
1165
1166
def _bootstrap(self):
1167
# Wrapper around the real bootstrap code that ignores
1168
# exceptions during interpreter cleanup. Those typically
1169
# happen when a daemon thread wakes up at an unfortunate
1170
# moment, finds the world around it destroyed, and raises some
1171
# random exception *** while trying to report the exception in
1172
# _bootstrap_inner() below ***. Those random exceptions
1173
# don't help anybody, and they confuse users, so we suppress
1174
# them. We suppress them only when it appears that the world
1175
# indeed has already been destroyed, so that exceptions in
1176
# _bootstrap_inner() during normal business hours are properly
1177
# reported. Also, we only suppress them for daemonic threads;
1178
# if a non-daemonic encounters this, something else is wrong.
1179
try:
1180
14546
self._bootstrap_inner()
1181
except:
1182
if self._daemonic and _sys is None:
1183
return
1184
raise
1185
1186
def _set_ident(self):
1187
self._ident = get_ident()
1188
1189
if _HAVE_THREAD_NATIVE_ID:
1190
def _set_native_id(self):
1191
self._native_id = get_native_id()
1192
1193
def _set_os_name(self):
1194
if _set_name is None or not self._name:
1195
return
1196
try:
1197
_set_name(self._name)
1198
except OSError:
1199
pass
1200
1201
def _bootstrap_inner(self):
1202
try:
1203
self._set_ident()
1204
if _HAVE_THREAD_NATIVE_ID:
1205
self._set_native_id()
1206
self._set_os_name()
1207
self._started.set()
1208
with _active_limbo_lock:
1209
_active[self._ident] = self
1210
del _limbo[self]
1211
1212
if _trace_hook:
1213
_sys.settrace(_trace_hook)
1214
if _profile_hook:
1215
_sys.setprofile(_profile_hook)
1216
1217
try:
1218
14546
self._context.run(self.run)
1219
except:
1220
self._invoke_excepthook(self)
1221
finally:
1222
self._delete()
1223
1224
def _delete(self):
1225
"Remove current thread from the dict of currently running threads."
1226
with _active_limbo_lock:
1227
del _active[get_ident()]
1228
# There must not be any python code between the previous line
1229
# and after the lock is released. Otherwise a tracing function
1230
# could try to acquire the lock again in the same thread, (in
1231
# current_thread()), and would block.
1232
1233
def join(self, timeout=None):
1234
"""Wait until the thread terminates.
1235
1236
This blocks the calling thread until the thread whose join() method is
1237
called terminates -- either normally or through an unhandled exception
1238
or until the optional timeout occurs.
1239
1240
When the timeout argument is present and not None, it should be a
1241
floating-point number specifying a timeout for the operation in seconds
1242
(or fractions thereof). As join() always returns None, you must call
1243
is_alive() after join() to decide whether a timeout happened -- if the
1244
thread is still alive, the join() call timed out.
1245
1246
When the timeout argument is not present or None, the operation will
1247
block until the thread terminates.
1248
1249
A thread can be join()ed many times.
1250
1251
join() raises a RuntimeError if an attempt is made to join the current
1252
thread as that would cause a deadlock. It is also an error to join() a
1253
thread before it has been started and attempts to do so raises the same
1254
exception.
1255
1256
"""
1257
if not self._initialized:
1258
raise RuntimeError("Thread.__init__() not called")
1259
if not self._started.is_set():
1260
raise RuntimeError("cannot join thread before it is started")
1261
if self is current_thread():
1262
raise RuntimeError("cannot join current thread")
1263
1264
# the behavior of a negative timeout isn't documented, but
1265
# historically .join(timeout=x) for x<0 has acted as if timeout=0
1266
if timeout is not None:
1267
timeout = max(timeout, 0)
1268
1269
self._os_thread_handle.join(timeout)
1270
1271
@property
1272
def name(self):
1273
"""A string used for identification purposes only.
1274
1275
It has no semantics. Multiple threads may be given the same name. The
1276
initial name is set by the constructor.
1277
1278
"""
1279
assert self._initialized, "Thread.__init__() not called"
1280
return self._name
1281
1282
@name.setter
1283
def name(self, name):
1284
assert self._initialized, "Thread.__init__() not called"
1285
self._name = str(name)
1286
if get_ident() == self._ident:
1287
self._set_os_name()
1288
1289
@property
1290
def ident(self):
1291
"""Thread identifier of this thread or None if it has not been started.
1292
1293
This is a nonzero integer. See the get_ident() function. Thread
1294
identifiers may be recycled when a thread exits and another thread is
1295
created. The identifier is available even after the thread has exited.
1296
1297
"""
1298
assert self._initialized, "Thread.__init__() not called"
1299
return self._ident
1300
1301
if _HAVE_THREAD_NATIVE_ID:
1302
@property
1303
def native_id(self):
1304
"""Native integral thread ID of this thread, or None if it has not been started.
1305
1306
This is a non-negative integer. See the get_native_id() function.
1307
This represents the Thread ID as reported by the kernel.
1308
1309
"""
1310
assert self._initialized, "Thread.__init__() not called"
1311
return self._native_id
1312
1313
def is_alive(self):
1314
"""Return whether the thread is alive.
1315
1316
This method returns True just before the run() method starts until just
1317
after the run() method terminates. See also the module function
1318
enumerate().
1319
1320
"""
1321
assert self._initialized, "Thread.__init__() not called"
1322
return self._started.is_set() and not self._os_thread_handle.is_done()
1323
1324
@property
1325
def daemon(self):
1326
"""A boolean value indicating whether this thread is a daemon thread.
1327
1328
This must be set before start() is called, otherwise RuntimeError is
1329
raised. Its initial value is inherited from the creating thread; the
1330
main thread is not a daemon thread and therefore all threads created in
1331
the main thread default to daemon = False.
1332
1333
The entire Python program exits when only daemon threads are left.
1334
1335
"""
1336
assert self._initialized, "Thread.__init__() not called"
1337
return self._daemonic
1338
1339
@daemon.setter
1340
def daemon(self, daemonic):
1341
if not self._initialized:
1342
raise RuntimeError("Thread.__init__() not called")
1343
if daemonic and not _daemon_threads_allowed():
1344
raise RuntimeError('daemon threads are disabled in this interpreter')
1345
if self._started.is_set():
1346
raise RuntimeError("cannot set daemon status of active thread")
1347
self._daemonic = daemonic
1348
1349
def isDaemon(self):
1350
"""Return whether this thread is a daemon.
1351
1352
This method is deprecated, use the daemon attribute instead.
1353
1354
"""
1355
import warnings
1356
warnings.warn('isDaemon() is deprecated, get the daemon attribute instead',
1357
DeprecationWarning, stacklevel=2)
1358
return self.daemon
1359
1360
def setDaemon(self, daemonic):
1361
"""Set whether this thread is a daemon.
1362
1363
This method is deprecated, use the .daemon property instead.
1364
1365
"""
1366
import warnings
1367
warnings.warn('setDaemon() is deprecated, set the daemon attribute instead',
1368
DeprecationWarning, stacklevel=2)
1369
self.daemon = daemonic
1370
1371
def getName(self):
1372
"""Return a string used for identification purposes only.
1373
1374
This method is deprecated, use the name attribute instead.
1375
1376
"""
1377
import warnings
1378
warnings.warn('getName() is deprecated, get the name attribute instead',
1379
DeprecationWarning, stacklevel=2)
1380
return self.name
1381
1382
def setName(self, name):
1383
"""Set the name string for this thread.
1384
1385
This method is deprecated, use the name attribute instead.
1386
1387
"""
1388
import warnings
1389
warnings.warn('setName() is deprecated, set the name attribute instead',
1390
DeprecationWarning, stacklevel=2)
1391
self.name = name
1392
1393
1394
try:
1395
from _thread import (_excepthook as excepthook,
1396
_ExceptHookArgs as ExceptHookArgs)
1397
except ImportError:
1398
# Simple Python implementation if _thread._excepthook() is not available
1399
from traceback import print_exception as _print_exception
1400
from collections import namedtuple
1401
1402
_ExceptHookArgs = namedtuple(
1403
'ExceptHookArgs',
1404
'exc_type exc_value exc_traceback thread')
1405
1406
def ExceptHookArgs(args):
1407
return _ExceptHookArgs(*args)
1408
1409
def excepthook(args, /):
1410
"""
1411
Handle uncaught Thread.run() exception.
1412
"""
1413
if args.exc_type == SystemExit:
1414
# silently ignore SystemExit
1415
return
1416
1417
if _sys is not None and _sys.stderr is not None:
1418
stderr = _sys.stderr
1419
elif args.thread is not None:
1420
stderr = args.thread._stderr
1421
if stderr is None:
1422
# do nothing if sys.stderr is None and sys.stderr was None
1423
# when the thread was created
1424
return
1425
else:
1426
# do nothing if sys.stderr is None and args.thread is None
1427
return
1428
1429
if args.thread is not None:
1430
name = args.thread.name
1431
else:
1432
name = get_ident()
1433
print(f"Exception in thread {name}:",
1434
file=stderr, flush=True)
1435
_print_exception(args.exc_type, args.exc_value, args.exc_traceback,
1436
file=stderr)
1437
stderr.flush()
1438
1439
1440
# Original value of threading.excepthook
1441
__excepthook__ = excepthook
1442
1443
1444
def _make_invoke_excepthook():
1445
# Create a local namespace to ensure that variables remain alive
1446
# when _invoke_excepthook() is called, even if it is called late during
1447
# Python shutdown. It is mostly needed for daemon threads.
1448
1449
old_excepthook = excepthook
1450
old_sys_excepthook = _sys.excepthook
1451
if old_excepthook is None:
1452
raise RuntimeError("threading.excepthook is None")
1453
if old_sys_excepthook is None:
1454
raise RuntimeError("sys.excepthook is None")
1455
1456
sys_exc_info = _sys.exc_info
1457
local_print = print
1458
local_sys = _sys
1459
1460
def invoke_excepthook(thread):
1461
global excepthook
1462
try:
1463
hook = excepthook
1464
if hook is None:
1465
hook = old_excepthook
1466
1467
args = ExceptHookArgs([*sys_exc_info(), thread])
1468
1469
hook(args)
1470
except Exception as exc:
1471
exc.__suppress_context__ = True
1472
del exc
1473
1474
if local_sys is not None and local_sys.stderr is not None:
1475
stderr = local_sys.stderr
1476
else:
1477
stderr = thread._stderr
1478
1479
local_print("Exception in threading.excepthook:",
1480
file=stderr, flush=True)
1481
1482
if local_sys is not None and local_sys.excepthook is not None:
1483
sys_excepthook = local_sys.excepthook
1484
else:
1485
sys_excepthook = old_sys_excepthook
1486
1487
sys_excepthook(*sys_exc_info())
1488
finally:
1489
# Break reference cycle (exception stored in a variable)
1490
args = None
1491
1492
return invoke_excepthook
1493
1494
1495
# The timer class was contributed by Itamar Shtull-Trauring
1496
1497
class Timer(Thread):
1498
"""Call a function after a specified number of seconds:
1499
1500
t = Timer(30.0, f, args=None, kwargs=None)
1501
t.start()
1502
t.cancel() # stop the timer's action if it's still waiting
1503
1504
"""
1505
1506
def __init__(self, interval, function, args=None, kwargs=None):
1507
Thread.__init__(self)
1508
self.interval = interval
1509
self.function = function
1510
self.args = args if args is not None else []
1511
self.kwargs = kwargs if kwargs is not None else {}
1512
self.finished = Event()
1513
1514
def cancel(self):
1515
"""Stop the timer if it hasn't finished yet."""
1516
self.finished.set()
1517
1518
def run(self):
1519
self.finished.wait(self.interval)
1520
if not self.finished.is_set():
1521
self.function(*self.args, **self.kwargs)
1522
self.finished.set()
1523
1524
1525
# Special thread class to represent the main thread
1526
1527
class _MainThread(Thread):
1528
1529
def __init__(self):
1530
Thread.__init__(self, name="MainThread", daemon=False)
1531
self._started.set()
1532
self._ident = _get_main_thread_ident()
1533
self._os_thread_handle = _make_thread_handle(self._ident)
1534
if _HAVE_THREAD_NATIVE_ID:
1535
self._set_native_id()
1536
with _active_limbo_lock:
1537
_active[self._ident] = self
1538
1539
1540
# Helper thread-local instance to detect when a _DummyThread
1541
# is collected. Not a part of the public API.
1542
_thread_local_info = local()
1543
1544
1545
class _DeleteDummyThreadOnDel:
1546
'''
1547
Helper class to remove a dummy thread from threading._active on __del__.
1548
'''
1549
1550
def __init__(self, dummy_thread):
1551
self._dummy_thread = dummy_thread
1552
self._tident = dummy_thread.ident
1553
# Put the thread on a thread local variable so that when
1554
# the related thread finishes this instance is collected.
1555
#
1556
# Note: no other references to this instance may be created.
1557
# If any client code creates a reference to this instance,
1558
# the related _DummyThread will be kept forever!
1559
_thread_local_info._track_dummy_thread_ref = self
1560
1561
def __del__(self, _active_limbo_lock=_active_limbo_lock, _active=_active):
1562
with _active_limbo_lock:
1563
if _active.get(self._tident) is self._dummy_thread:
1564
_active.pop(self._tident, None)
1565
1566
1567
# Dummy thread class to represent threads not started here.
1568
# These should be added to `_active` and removed automatically
1569
# when they die, although they can't be waited for.
1570
# Their purpose is to return *something* from current_thread().
1571
# They are marked as daemon threads so we won't wait for them
1572
# when we exit (conform previous semantics).
1573
1574
class _DummyThread(Thread):
1575
1576
def __init__(self):
1577
Thread.__init__(self, name=_newname("Dummy-%d"),
1578
daemon=_daemon_threads_allowed())
1579
self._started.set()
1580
self._set_ident()
1581
self._os_thread_handle = _make_thread_handle(self._ident)
1582
if _HAVE_THREAD_NATIVE_ID:
1583
self._set_native_id()
1584
with _active_limbo_lock:
1585
_active[self._ident] = self
1586
_DeleteDummyThreadOnDel(self)
1587
1588
def is_alive(self):
1589
if not self._os_thread_handle.is_done() and self._started.is_set():
1590
return True
1591
raise RuntimeError("thread is not alive")
1592
1593
def join(self, timeout=None):
1594
raise RuntimeError("cannot join a dummy thread")
1595
1596
def _after_fork(self, new_ident=None):
1597
if new_ident is not None:
1598
self.__class__ = _MainThread
1599
self._name = 'MainThread'
1600
self._daemonic = False
1601
Thread._after_fork(self, new_ident=new_ident)
1602
1603
1604
# Global API functions
1605
1606
def current_thread():
1607
"""Return the current Thread object, corresponding to the caller's thread of control.
1608
1609
If the caller's thread of control was not created through the threading
1610
module, a dummy thread object with limited functionality is returned.
1611
1612
"""
1613
try:
1614
return _active[get_ident()]
1615
except KeyError:
1616
return _DummyThread()
1617
1618
def currentThread():
1619
"""Return the current Thread object, corresponding to the caller's thread of control.
1620
1621
This function is deprecated, use current_thread() instead.
1622
1623
"""
1624
import warnings
1625
warnings.warn('currentThread() is deprecated, use current_thread() instead',
1626
DeprecationWarning, stacklevel=2)
1627
return current_thread()
1628
1629
def active_count():
1630
"""Return the number of Thread objects currently alive.
1631
1632
The returned count is equal to the length of the list returned by
1633
enumerate().
1634
1635
"""
1636
# NOTE: if the logic in here ever changes, update Modules/posixmodule.c
1637
# warn_about_fork_with_threads() to match.
1638
with _active_limbo_lock:
1639
return len(_active) + len(_limbo)
1640
1641
def activeCount():
1642
"""Return the number of Thread objects currently alive.
1643
1644
This function is deprecated, use active_count() instead.
1645
1646
"""
1647
import warnings
1648
warnings.warn('activeCount() is deprecated, use active_count() instead',
1649
DeprecationWarning, stacklevel=2)
1650
return active_count()
1651
1652
def _enumerate():
1653
# Same as enumerate(), but without the lock. Internal use only.
1654
return list(_active.values()) + list(_limbo.values())
1655
1656
def enumerate():
1657
"""Return a list of all Thread objects currently alive.
1658
1659
The list includes daemonic threads, dummy thread objects created by
1660
current_thread(), and the main thread. It excludes terminated threads and
1661
threads that have not yet been started.
1662
1663
"""
1664
with _active_limbo_lock:
1665
return list(_active.values()) + list(_limbo.values())
1666
1667
1668
_threading_atexits = []
1669
_SHUTTING_DOWN = False
1670
1671
def _register_atexit(func, *arg, **kwargs):
1672
"""CPython internal: register *func* to be called before joining threads.
1673
1674
The registered *func* is called with its arguments just before all
1675
non-daemon threads are joined in `_shutdown()`. It provides a similar
1676
purpose to `atexit.register()`, but its functions are called prior to
1677
threading shutdown instead of interpreter shutdown.
1678
1679
For similarity to atexit, the registered functions are called in reverse.
1680
"""
1681
if _SHUTTING_DOWN:
1682
raise RuntimeError("can't register atexit after shutdown")
1683
1684
_threading_atexits.append(lambda: func(*arg, **kwargs))
1685
1686
1687
from _thread import stack_size
1688
1689
# Create the main thread object,
1690
# and make it available for the interpreter
1691
# (Py_Main) as threading._shutdown.
1692
1693
_main_thread = _MainThread()
1694
1695
def _shutdown():
1696
"""
1697
Wait until the Python thread state of all non-daemon threads get deleted.
1698
"""
1699
# Obscure: other threads may be waiting to join _main_thread. That's
1700
# dubious, but some code does it. We can't wait for it to be marked as done
1701
# normally - that won't happen until the interpreter is nearly dead. So
1702
# mark it done here.
1703
if _main_thread._os_thread_handle.is_done() and _is_main_interpreter():
1704
# _shutdown() was already called, but threads might have started
1705
# in the meantime.
1706
return _thread_shutdown()
1707
1708
global _SHUTTING_DOWN
1709
_SHUTTING_DOWN = True
1710
1711
# Call registered threading atexit functions before threads are joined.
1712
# Order is reversed, similar to atexit.
1713
for atexit_call in reversed(_threading_atexits):
1714
atexit_call()
1715
1716
if _is_main_interpreter():
1717
_main_thread._os_thread_handle._set_done()
1718
1719
# Wait for all non-daemon threads to exit.
1720
_thread_shutdown()
1721
1722
1723
def main_thread():
1724
"""Return the main thread object.
1725
1726
In normal conditions, the main thread is the thread from which the
1727
Python interpreter was started.
1728
"""
1729
# XXX Figure this out for subinterpreters. (See gh-75698.)
1730
return _main_thread
1731
1732
1733
def _after_fork():
1734
"""
1735
Cleanup threading module state that should not exist after a fork.
1736
"""
1737
# Reset _active_limbo_lock, in case we forked while the lock was held
1738
# by another (non-forked) thread. http://bugs.python.org/issue874900
1739
global _active_limbo_lock, _main_thread
1740
_active_limbo_lock = RLock()
1741
1742
# fork() only copied the current thread; clear references to others.
1743
new_active = {}
1744
1745
try:
1746
current = _active[get_ident()]
1747
except KeyError:
1748
# fork() was called in a thread which was not spawned
1749
# by threading.Thread. For example, a thread spawned
1750
# by thread.start_new_thread().
1751
current = _MainThread()
1752
1753
_main_thread = current
1754
1755
with _active_limbo_lock:
1756
# Dangling thread instances must still have their locks reset,
1757
# because someone may join() them.
1758
threads = set(_enumerate())
1759
threads.update(_dangling)
1760
for thread in threads:
1761
# Any lock/condition variable may be currently locked or in an
1762
# invalid state, so we reinitialize them.
1763
if thread is current:
1764
# This is the one and only active thread.
1765
ident = get_ident()
1766
thread._after_fork(new_ident=ident)
1767
new_active[ident] = thread
1768
else:
1769
# All the others are already stopped.
1770
thread._after_fork()
1771
1772
_limbo.clear()
1773
_active.clear()
1774
_active.update(new_active)
1775
assert len(_active) == 1
1776
1777
1778
if hasattr(_os, "register_at_fork"):
1779
_os.register_at_fork(after_in_child=_after_fork)