homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: threading.Timer object is affected by changes to system time: Python locks should use a monotonic clock if available
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.5
process
Status: closed Resolution: duplicate
Dependencies: Superseder: threading.Condition.wait(timeout) should use a monotonic clock: use pthread_condattr_setclock(CLOCK_MONOTONIC)
View: 12822
Assigned To: Nosy List: Matthias Schmidt, anikey, vstinner, winfreak
Priority: normal Keywords:

Created on 2017年08月23日 20:47 by winfreak, last changed 2022年04月11日 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
timer_testcase.py winfreak, 2017年08月23日 20:47
test_monotonic.py winfreak, 2017年08月23日 20:47
Messages (8)
msg300765 - (view) Author: Thomas Keppler (winfreak) Date: 2017年08月23日 20:47
Hi,
I have been playing around with threading.Timer objects as timeouts for a project and noticed that my timeouts are affected by system time changes.
To test this, I have written a small demonstration script (timer_testcase.py) which you can find in the attachments. I would expect that after 120 seconds, a "Hello!" message will appear on the screen regardless of system time changes.
If you run the script like you would normally, you will see that it will work properly and my expectations are met. Now, run it again and immediately use "date +%T -s "HH:MM:SS"" where the time is >= 2 mins in the future. You will notice that the timer will latch immediately instead of waiting those 120 seconds before latching.
I have read Lib/threading.py to a certain extent and it seems like Timer objects are using monotonic time already because they use Events which use Conditions themselves, which references a "_timer" function that is just an alias for time.monotonic as one can see at the top of the file.
Then I checked out if the monotonic time works as expected (test_monotonic.py) by just jumping back and forth "in time", everything seemed to be normal.
Am I making a mistake and if so, where?
Thanks for any of your answers.
--
Best regards
Thomas
Environment: I'm using Python 3.5.3 on Debian 9.1 "Stretch" on x86_64.
msg302249 - (view) Author: Matthias Schmidt (Matthias Schmidt) Date: 2017年09月15日 12:52
Hi,
any news on this issue? We are facing this one as well and looking forward for a fix/solution.
Cheers,
Matthis Schmidt
msg302257 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017年09月15日 14:32
threading.Timer is implemented with threading.Event.wait(timeout) which is implemented with threading.Condition.wait(timeout).
threading.Condition.wait(timeout) creates a lock called "waiter" and uses it to implement the wait:
 waiter.acquire(True, timeout)
So at the end of the chain, you find a lock created by _thread.allocate_lock() and the Lock.acquire(True, timeout) call.
At the C level, a lock is created by PyThread_allocate_lock(). The implementation of PyThread_allocate_lock() depends on the platform. Check:
>>> sys.thread_info
sys.thread_info(name='pthread', lock='semaphore', version='NPTL 2.25')
So in my case (Fedora 25), a Python lock is implemented as a semaphore:
* create the lock: sem_init()
* acquire the lock with a timeout: sem_timedwait(thelock, &ts)
The problem is that the sem_timedwait() function of the glibc doesn't allow to specify which clock is used:
https://sourceware.org/bugzilla/show_bug.cgi?id=14717
The second problem is that the glibc relies on the Linux kernel, and the kernel doesn't support specifiying a clock (extract of the glib bug):
"It seems this would need kernel work"
--
For sys.thread_info.lock == "mutex+cond", PyThread_allocate_lock(timeout) is implemented with pthread_mutex_lock() + pthread_cond_timedwait(). The good news is that this API allows to specify the clock:
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
pthread_cond_init(&cond, &attr);
... I already created bpo-23428 to call "pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);" in Python, it was 2 years ago ;-)
msg302259 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017年09月15日 14:54
> ... I already created bpo-23428 to call "pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);" in Python, it was 2 years ago ;-)
See also bpo-12822: "NewGIL should use CLOCK_MONOTONIC if possible".
msg303893 - (view) Author: Thomas Keppler (winfreak) Date: 2017年10月08日 02:04
Hello Victor,
thank you for your update on this issue.
By looking through the other bug reports you listed, it looks as if measures were implemented but never merged. Am I right with this observation? If so, will we ever see a switch over to monotonic time?
Thanks for the info :)
--
Best regards
Thomas
msg303934 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017年10月09日 09:33
> it looks as if measures were implemented but never merged.
The blocker issue is that sem_timedwait() doesn't support CLOCK_MONOTONIC. The glibc has to be enhanced to support this new feature.
msg333798 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019年01月16日 22:26
I'm sorrry, I read the issue too quickly and misunderstood it. I guess that it's a duplicate of bpo-23428: "Use the monotonic clock for thread conditions on POSIX platforms". This issue is blocked the libc...
msg333840 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2019年01月17日 10:04
> I'm sorrry, I read the issue too quickly and misunderstood it. I guess that it's a duplicate of bpo-23428: "Use the monotonic clock for thread conditions on POSIX platforms". This issue is blocked the libc...
Oops, I wanted to post this comment on bpo-35747... There are too many duplicates of bpo-23428...
I close this issue as a duplicate of bpo-23428.
History
Date User Action Args
2022年04月11日 14:58:51adminsetgithub: 75450
2021年10月01日 08:49:02vstinnersetsuperseder: Use the monotonic clock for thread conditions on POSIX platforms -> threading.Condition.wait(timeout) should use a monotonic clock: use pthread_condattr_setclock(CLOCK_MONOTONIC)
2019年01月17日 10:04:50vstinnersetstatus: open -> closed
superseder: Use the monotonic clock for thread conditions on POSIX platforms
messages: + msg333840

resolution: duplicate
stage: resolved
2019年01月16日 22:26:11vstinnersetmessages: + msg333798
2018年07月27日 10:37:15anikeysetnosy: + anikey
2017年10月09日 09:33:52vstinnersetmessages: + msg303934
2017年10月08日 02:04:38winfreaksetmessages: + msg303893
2017年09月15日 14:55:02vstinnersettitle: threading.Timer object is affected by changes to system time -> threading.Timer object is affected by changes to system time: Python locks should use a monotonic clock if available
2017年09月15日 14:54:35vstinnersetmessages: + msg302259
2017年09月15日 14:32:44vstinnersetmessages: + msg302257
2017年09月15日 12:52:25Matthias Schmidtsetnosy: + Matthias Schmidt
messages: + msg302249
2017年08月24日 10:38:51pitrousetnosy: + vstinner
2017年08月23日 20:47:45winfreaksetfiles: + test_monotonic.py
2017年08月23日 20:47:35winfreakcreate

AltStyle によって変換されたページ (->オリジナル) /