bpo-32025: Add time.thread_time() (#4410) · python/cpython@4bd41c9 · GitHub
Skip to content

Commit 4bd41c9

Browse files
authored
bpo-32025: Add time.thread_time() (#4410)
* bpo-32025: Add time.thread_time() * Add missing #endif * Add NEWS blurb * Add docs and whatsnew * Address review comments * Review comments
1 parent 762b957 commit 4bd41c9

5 files changed

Lines changed: 206 additions & 0 deletions

File tree

Doc/library/time.rst

Lines changed: 27 additions & 0 deletions

Doc/whatsnew/3.7.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,10 @@ Add new clock identifiers:
372372
the time the system has been running and not suspended, providing accurate
373373
uptime measurement, both absolute and interval.
374374

375+
Added functions :func:`time.thread_time` and :func:`time.thread_time_ns`
376+
to get per-thread CPU time measurements.
377+
(Contributed by Antoine Pitrou in :issue:`32025`.)
378+
375379
unittest.mock
376380
-------------
377381

Lib/test/test_time.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ class _PyTime(enum.IntEnum):
4747
)
4848

4949

50+
def busy_wait(duration):
51+
deadline = time.monotonic() + duration
52+
while time.monotonic() < deadline:
53+
pass
54+
55+
5056
class TimeTestCase(unittest.TestCase):
5157

5258
def setUp(self):
@@ -81,6 +87,10 @@ def check_ns(sec, ns):
8187
check_ns(time.process_time(),
8288
time.process_time_ns())
8389

90+
if hasattr(time, 'thread_time'):
91+
check_ns(time.thread_time(),
92+
time.thread_time_ns())
93+
8494
if hasattr(time, 'clock_gettime'):
8595
check_ns(time.clock_gettime(time.CLOCK_REALTIME),
8696
time.clock_gettime_ns(time.CLOCK_REALTIME))
@@ -486,10 +496,57 @@ def test_process_time(self):
486496
# on Windows
487497
self.assertLess(stop - start, 0.020)
488498

499+
# process_time() should include CPU time spent in any thread
500+
start = time.process_time()
501+
busy_wait(0.100)
502+
stop = time.process_time()
503+
self.assertGreaterEqual(stop - start, 0.020) # machine busy?
504+
505+
t = threading.Thread(target=busy_wait, args=(0.100,))
506+
start = time.process_time()
507+
t.start()
508+
t.join()
509+
stop = time.process_time()
510+
self.assertGreaterEqual(stop - start, 0.020) # machine busy?
511+
489512
info = time.get_clock_info('process_time')
490513
self.assertTrue(info.monotonic)
491514
self.assertFalse(info.adjustable)
492515

516+
def test_thread_time(self):
517+
if not hasattr(time, 'thread_time'):
518+
if sys.platform.startswith(('linux', 'win')):
519+
self.fail("time.thread_time() should be available on %r"
520+
% (sys.platform,))
521+
else:
522+
self.skipTest("need time.thread_time")
523+
524+
# thread_time() should not include time spend during a sleep
525+
start = time.thread_time()
526+
time.sleep(0.100)
527+
stop = time.thread_time()
528+
# use 20 ms because thread_time() has usually a resolution of 15 ms
529+
# on Windows
530+
self.assertLess(stop - start, 0.020)
531+
532+
# thread_time() should include CPU time spent in current thread...
533+
start = time.thread_time()
534+
busy_wait(0.100)
535+
stop = time.thread_time()
536+
self.assertGreaterEqual(stop - start, 0.020) # machine busy?
537+
538+
# ...but not in other threads
539+
t = threading.Thread(target=busy_wait, args=(0.100,))
540+
start = time.thread_time()
541+
t.start()
542+
t.join()
543+
stop = time.thread_time()
544+
self.assertLess(stop - start, 0.020)
545+
546+
info = time.get_clock_info('thread_time')
547+
self.assertTrue(info.monotonic)
548+
self.assertFalse(info.adjustable)
549+
493550
@unittest.skipUnless(hasattr(time, 'clock_settime'),
494551
'need time.clock_settime')
495552
def test_monotonic_settime(self):
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add time.thread_time() and time.thread_time_ns()

Modules/timemodule.c

Lines changed: 117 additions & 0 deletions

0 commit comments

Comments
 (0)