标签归档:sleep

python的time.sleep()有多准确?

问题:python的time.sleep()有多准确?

我可以给它加上浮点数,例如

time.sleep(0.5)

但是它有多精确?如果我给它

time.sleep(0.05)

它真的会睡约50毫秒吗?

I can give it floating point numbers, such as

time.sleep(0.5)

but how accurate is it? If i give it

time.sleep(0.05)

will it really sleep about 50 ms?


回答 0

time.sleep函数的准确性取决于您底层操作系统的睡眠准确性。对于非实时操作系统(如普通Windows),您可以睡眠的最小间隔约为10-13毫秒。在最小的10-13毫秒以上的时间里,我已经看到了几毫秒内的准确睡眠。

更新:就像在下面引用的文档中提到的那样,通常在一个循环中进行睡眠,这样可以确保在早起的情况下回到睡眠状态。

我还应该提到,如果您正在运行Ubuntu,则可以通过安装rt内核软件包(至少在Ubuntu 10.04 LTS中)来尝试伪实时内核(带有RT_PREEMPT补丁集)。

编辑:校正非实时Linux内核的最小睡眠间隔要比1ms再接近10ms,但是它以不确定的方式变化。

The accuracy of the time.sleep function depends on your underlying OS’s sleep accuracy. For non-realtime OS’s like a stock Windows the smallest interval you can sleep for is about 10-13ms. I have seen accurate sleeps within several milliseconds of that time when above the minimum 10-13ms.

Update: Like mentioned in the docs cited below, it’s common to do the sleep in a loop that will make sure to go back to sleep if it wakes you up early.

I should also mention that if you are running Ubuntu you can try out a pseudo real-time kernel (with the RT_PREEMPT patch set) by installing the rt kernel package (at least in Ubuntu 10.04 LTS).

EDIT: Correction non-realtime Linux kernels have minimum sleep interval much closer to 1ms then 10ms but it varies in a non-deterministic manner.


回答 1

人们对操作系统和内核之间的差异是完全正确的,但是我在Ubuntu中看不到任何粒度,在MS7中却看到1 ms的粒度。建议使用time.sleep的不同实现方式,而不仅是不同的滴答频率。仔细检查可以发现,在Ubuntu中粒度为1μs,但这是由于我用来测量精度的time.time函数所致。

People are quite right about the differences between operating systems and kernels, but I do not see any granularity in Ubuntu and I see a 1 ms granularity in MS7. Suggesting a different implementation of time.sleep, not just a different tick rate. Closer inspection suggests a 1μs granularity in Ubuntu by the way, but that is due to the time.time function that I use for measuring the accuracy.


回答 2

文档中

在另一方面,精度 time()sleep()优于他们的UNIX的等价:时间被表示为浮点数, time()返回最准确的时间(使用的Unix gettimeofday 如果有的话),和sleep()将接受具有非零分数的时间(Unix的select使用实施此操作(如果有)。

更具体 WRT sleep()

暂停执行指定的秒数。该自变量可以是浮点数,以指示更精确的睡眠时间。实际的暂停时间可能少于请求的暂停时间,因为任何捕获到的信号都会终止该sleep()信号捕获例程的后续执行。而且,由于系统中其他活动的调度,暂停时间可能比请求的时间任意数量。

From the documentation:

On the other hand, the precision of time() and sleep() is better than their Unix equivalents: times are expressed as floating point numbers, time() returns the most accurate time available (using Unix gettimeofday where available), and sleep() will accept a time with a nonzero fraction (Unix select is used to implement this, where available).

And more specifically w.r.t. sleep():

Suspend execution for the given number of seconds. The argument may be a floating point number to indicate a more precise sleep time. The actual suspension time may be less than that requested because any caught signal will terminate the sleep() following execution of that signal’s catching routine. Also, the suspension time may be longer than requested by an arbitrary amount because of the scheduling of other activity in the system.


回答 3

这是我对Wilbert的回答的后续内容:对于Mac OS X Yosemite来说也是相同的,因为还没有被提及。

看起来很多时候它的睡眠时间约为您请求时间的1.25倍,有时甚至是您请求时间的1到1.25倍之间。它几乎从来不会(约1000个样本中的两倍)睡眠时间超过您请求时间的1.25倍。

同样(未明确显示),1.25关系似乎保持良好,直到您低于约0.2 ms,此后开始变得有点模糊。此外,在请求的时间超过20 ms之后,实际时间似乎比您请求的时间稳定了大约5 ms。

同样,它似乎是sleep()OS X中与Windows或Linux内核Wilbert使用的完全不同的实现。

Here’s my follow-up to Wilbert’s answer: the same for Mac OS X Yosemite, since it’s not been mentioned much yet.

Looks like a lot of the time it sleeps about 1.25 times the time that you request and sometimes sleeps between 1 and 1.25 times the time you request. It almost never (~twice out of 1000 samples) sleeps significantly more than 1.25 times the time you request.

Also (not shown explicitly) the 1.25 relationship seems to hold pretty well until you get below about 0.2 ms, after which it starts get a little fuzzy. Additionally, the actual time seems to settle to about 5 ms longer than you request after the amount of time requested gets above 20 ms.

Again, it appears to be a completely different implementation of sleep() in OS X than in Windows or whichever Linux kernal Wilbert was using.


回答 4

为什么不找出来:

from datetime import datetime
import time

def check_sleep(amount):
    start = datetime.now()
    time.sleep(amount)
    end = datetime.now()
    delta = end-start
    return delta.seconds + delta.microseconds/1000000.

error = sum(abs(check_sleep(0.050)-0.050) for i in xrange(100))*10
print "Average error is %0.2fms" % error

作为记录,我在HTPC和笔记本电脑(均为linux机器)上均出现约0.1ms的错误。

Why don’t you find out:

from datetime import datetime
import time

def check_sleep(amount):
    start = datetime.now()
    time.sleep(amount)
    end = datetime.now()
    delta = end-start
    return delta.seconds + delta.microseconds/1000000.

error = sum(abs(check_sleep(0.050)-0.050) for i in xrange(100))*10
print "Average error is %0.2fms" % error

For the record, I get around 0.1ms error on my HTPC and 2ms on my laptop, both linux machines.


回答 5

一个小的修正,几个人提到睡眠可以通过信号提前结束。在3.6文档中

在版本3.5中进行了更改:现在,即使睡眠被信号中断,该函数也将至少睡眠几秒,除非信号处理程序引发异常(有关原理,请参阅PEP 475)。

A small correction, several people mention that sleep can be ended early by a signal. In the 3.6 docs it says,

Changed in version 3.5: The function now sleeps at least secs even if the sleep is interrupted by a signal, except if the signal handler raises an exception (see PEP 475 for the rationale).


回答 6

您不能真正保证关于sleep()的任何东西,除非它至少会尽您最大的努力使您进入睡眠状态(信号可以在时间到了之前杀死您的睡眠,还有更多事情可以使它运行)长)。

可以肯定的是,您在标准台式机操作系统上所能获得的最小值约为16毫秒(计时器粒度加上切换上下文的时间),但尝试时与提供的参数的%偏差可能会很大。睡了十毫秒。

信号,其他持有GIL的线程,内核调度的乐趣,处理器速度的提高等等,都可能在线程/进程实际睡眠的持续时间内造成严重破坏。

You can’t really guarantee anything about sleep(), except that it will at least make a best effort to sleep as long as you told it (signals can kill your sleep before the time is up, and lots more things can make it run long).

For sure the minimum you can get on a standard desktop operating system is going to be around 16ms (timer granularity plus time to context switch), but chances are that the % deviation from the provided argument is going to be significant when you’re trying to sleep for 10s of milliseconds.

Signals, other threads holding the GIL, kernel scheduling fun, processor speed stepping, etc. can all play havoc with the duration your thread/process actually sleeps.


回答 7

如果您需要更高的精度或更少的睡眠时间,请考虑自己做:

import time

def sleep(duration, get_now=time.perf_counter):
    now = get_now()
    end = now + duration
    while now < end:
        now = get_now()

if you need more precision or lower sleep times, consider making your own:

import time

def sleep(duration, get_now=time.perf_counter):
    now = get_now()
    end = now + duration
    while now < end:
        now = get_now()

回答 8

最近在Windows 10上的Python 3.7上对此进行了测试。精度约为1毫秒。

Tested this recently on Python 3.7 on Windows 10. Precision was around 1ms.


回答 9

def start(self):
    sec_arg = 10.0
    cptr = 0
    time_start = time.time()
    time_init = time.time()
    while True:
        cptr += 1
        time_start = time.time()
        time.sleep(((time_init + (sec_arg * cptr)) - time_start ))

        # AND YOUR CODE .......
        t00 = threading.Thread(name='thread_request', target=self.send_request, args=([]))
        t00.start()

不要使用变量传递sleep()的参数,必须将计算直接插入sleep()


还有我的航站楼的归还

1─────17:20:16.891──────────────────

2──────17:20:18.891────────────────────

3──────17:20:20.891──────────────────

4──────17:20:22.891──────────────────

5──────17:20:24.891──────────────────

….

689───17:43:12.891────────────────────

690───17:43:14.890────────────────────

691───17:43:16.891────────────────────

692───17:43:18.890────────────────────

693───17:43:20.891────────────────────

727───17:44:28.891────────────────────

728───17:44:30.891────────────────────

729───17:44:32.891────────────────────

730───17:44:34.890──────────────────

731───17:44:36.891────────────────────

def start(self):
    sec_arg = 10.0
    cptr = 0
    time_start = time.time()
    time_init = time.time()
    while True:
        cptr += 1
        time_start = time.time()
        time.sleep(((time_init + (sec_arg * cptr)) - time_start ))

        # AND YOUR CODE .......
        t00 = threading.Thread(name='thread_request', target=self.send_request, args=([]))
        t00.start()

Do not use a variable to pass the argument of sleep (), you must insert the calculation directly into sleep ()


And the return of my terminal

1 ───── 17:20:16.891 ───────────────────

2 ───── 17:20:18.891 ───────────────────

3 ───── 17:20:20.891 ───────────────────

4 ───── 17:20:22.891 ───────────────────

5 ───── 17:20:24.891 ───────────────────

….

689 ─── 17:43:12.891 ────────────────────

690 ─── 17:43:14.890 ────────────────────

691 ─── 17:43:16.891 ────────────────────

692 ─── 17:43:18.890 ────────────────────

693 ─── 17:43:20.891 ────────────────────

727 ─── 17:44:28.891 ────────────────────

728 ─── 17:44:30.891 ────────────────────

729 ─── 17:44:32.891 ────────────────────

730 ─── 17:44:34.890 ────────────────────

731 ─── 17:44:36.891 ────────────────────


暂停Python程序的正确方法

问题:暂停Python程序的正确方法

我一直在使用该input功能来暂停脚本

print("something")
wait = input("PRESS ENTER TO CONTINUE.")
print("something")

有正式的方法吗?

I’ve been using the input function as a way to pause my scripts:

print("something")
wait = input("Press Enter to continue.")
print("something")

Is there a formal way to do this?


回答 0

对我来说似乎很好(或raw_input()在Python 2.X中)。或者,time.sleep()如果您想暂停一定的秒数,则可以使用。

import time
print("something")
time.sleep(5.5)    # pause 5.5 seconds
print("something")

It Seems fine to me (or raw_input() in Python 2.X). Alternatively, you could use time.sleep() if you want to pause for a certain number of seconds.

import time
print("something")
time.sleep(5.5)    # Pause 5.5 seconds
print("something")

回答 1

仅适用于Windows

import os
os.system("pause")

For Windows only, use:

import os
os.system("pause")

回答 2

我假设您想暂停而不输入

time.sleep(secs)

I assume you want to pause without input.

Use:

time.sleep(seconds)


回答 3

因此,我发现这在我的编码工作中非常有效。我只是程序的开头创建了一个函数

def pause():
    programPause = raw_input("Press the <ENTER> key to continue...")

现在我可以pause()在需要的时候使用该函数,就像编写批处理文件一样。例如,在这样的程序中:

import os
import system

def pause():
    programPause = raw_input("Press the <ENTER> key to continue...")

print("Think about what you ate for dinner last night...")
pause()

现在显然该程序没有目标,仅是示例目的,但是您可以准确地理解我的意思。

注意:对于Python 3,您需要使用input而不是raw_input

So, I found this to work very well in my coding endeavors. I simply created a function at the very beginning of my program,

def pause():
    programPause = raw_input("Press the <ENTER> key to continue...")

and now I can use the pause() function whenever I need to just as if I was writing a batch file. For example, in a program such as this:

import os
import system

def pause():
    programPause = raw_input("Press the <ENTER> key to continue...")

print("Think about what you ate for dinner last night...")
pause()

Now obviously this program has no objective and is just for example purposes, but you can understand precisely what I mean.

NOTE: For Python 3, you will need to use input as opposed to raw_input


回答 4

我有一个类似的问题,我正在使用信号:

import signal

def signal_handler(signal_number, frame):
    print "Proceed ..."

signal.signal(signal.SIGINT, signal_handler)
signal.pause()

因此,您为信号SIGINT注册了一个处理程序,并暂停等待任何信号。现在,从程序外部(例如,在bash中),您可以运行kill -2 <python_pid>,它将向您的python程序发送信号2(即SIGINT)。您的程序将调用您的注册处理程序并继续运行。

I have had a similar question and I was using signal:

import signal

def signal_handler(signal_number, frame):
    print "Proceed ..."

signal.signal(signal.SIGINT, signal_handler)
signal.pause()

So you register a handler for the signal SIGINT and pause waiting for any signal. Now from outside your program (e.g. in bash), you can run kill -2 <python_pid>, which will send signal 2 (i.e. SIGINT) to your python program. Your program will call your registered handler and proceed running.


回答 5

我在python2和3中使用以下命令来暂停代码执行,直到用户按下ENTER

import six
if six.PY2:
    raw_input("Press the <ENTER> key to continue...")
else:
    input("Press the <ENTER> key to continue...")

I use the following for Python 2 and Python 3 to pause code execution until user presses Enter

import six

if six.PY2:
    raw_input("Press the <Enter> key to continue...")
else:
    input("Press the <Enter> key to continue...")

回答 6

很简单:

raw_input("Press Enter to continue ...")
exit()

Very simple:

raw_input("Press Enter to continue ...")
exit()

回答 7

Print ("This is how you pause")

input()
Print ("This is how you pause")

input()

回答 8

正如mhawkesteveha的评论所指出的那样,对该确切问题的最佳答案将是:

对于较长的文本块,最好使用input('Press <ENTER> to continue')(或raw_input('Press <ENTER> to continue')在Python 2.x上)提示用户,而不是延迟时间。快速的阅读器不想等待延迟,慢速的阅读器可能希望在延迟上花费更多的时间,某人在阅读该延迟时可能会被打扰,并且需要更多的时间,依此类推。此外,如果某人经常使用该程序,他/她可能已经习惯了它的工作原理,甚至不需要阅读冗长的文字。让用户控制将文本块显示多长时间以供阅读,这是更友好的做法。

As pointed out by mhawke and steveha‘s comments, the best answer to this exact question would be:

For a long block of text, it is best to use input('Press <ENTER> to continue') (or raw_input('Press <ENTER> to continue') on Python 2.x) to prompt the user, rather than a time delay. Fast readers won’t want to wait for a delay, slow readers might want more time on the delay, someone might be interrupted while reading it and want a lot more time, etc. Also, if someone uses the program a lot, he/she may become used to how it works and not need to even read the long text. It’s just friendlier to let the user control how long the block of text is displayed for reading.


回答 9

我认为停止执行的最好方法是time.sleep()函数。如果仅在某些情况下需要暂停执行,则可以简单地实现以下if语句:

if somethinghappen:
    time.sleep(seconds)

您可以将else分支留空。

I think that the best way to stop the execution is the time.sleep() function.

If you need to suspend the execution only in certain cases you can simply implement an if statement like this:

if somethinghappen:
    time.sleep(seconds)

You can leave the else branch empty.


回答 10

我想我喜欢这种饮料。

import getpass
getpass.getpass("Press Enter to Continue")

它隐藏了用户键入的内容,这有助于弄清此处未使用输入。

但是请注意,在OSX平台上,它显示的密钥可能会造成混淆。


最好的解决方案可能是自己做与getpass模块类似的事情,而不进行read -s调用。也许使fg颜色与bg匹配?

I think I like this solution:

import getpass
getpass.getpass("Press Enter to Continue")

It hides whatever the user types in, which helps clarify that input is not used here.

But be mindful on the OS X platform. It displays a key which may be confusing.


Probably the best solution would be to do something similar to the getpass module yourself, without making a read -s call. Maybe making the foreground color match the background?


回答 11

通过这种方法,只需按以下指定的任何键即可恢复程序:

import keyboard
while True:
    key = keyboard.read_key()
    if key == 'space':  # you can put any key you like instead of 'space'
        break

相同的方法,但以另一种方式:

import keyboard
while True:
    if keyboard.is_pressed('space'):  # same, you can put any key you like instead of 'space'
        break

注意:您keyboard只需在shell或cmd中编写以下代码即可安装模块:

pip install keyboard

By this method, you can resume your program just by pressing any specified key you’ve specified that:

import keyboard
while True:
    key = keyboard.read_key()
    if key == 'space':  # You can put any key you like instead of 'space'
        break

The same method, but in another way:

import keyboard
while True:
    if keyboard.is_pressed('space'):  # The same. you can put any key you like instead of 'space'
        break

Note: you can install the keyboard module simply by writing this in you shell or cmd:

pip install keyboard

回答 12

为了实现跨Python 2/3的兼容性,可以input通过以下six库使用:

import six
six.moves.input( 'Press the <ENTER> key to continue...' )

For cross Python 2/3 compatibility, you can use input via the six library:

import six
six.moves.input( 'Press the <ENTER> key to continue...' )

time.sleep —休眠线程或进程?

问题:time.sleep —休眠线程或进程?

在Python for * nix中,是否time.sleep()阻塞线程或进程?

In Python for *nix, does time.sleep() block the thread or the process?


回答 0

它阻塞线程。如果在Python源代码中查看Modules / timemodule.c,您会看到在调用中floatsleep(),睡眠操作的实质部分包装在Py_BEGIN_ALLOW_THREADS和Py_END_ALLOW_THREADS块中,从而允许其他线程在当前线程继续执行一睡觉。您也可以使用简单的python程序进行测试:

import time
from threading import Thread

class worker(Thread):
    def run(self):
        for x in xrange(0,11):
            print x
            time.sleep(1)

class waiter(Thread):
    def run(self):
        for x in xrange(100,103):
            print x
            time.sleep(5)

def run():
    worker().start()
    waiter().start()

将打印:

>>> thread_test.run()
0
100
>>> 1
2
3
4
5
101
6
7
8
9
10
102

It blocks the thread. If you look in Modules/timemodule.c in the Python source, you’ll see that in the call to floatsleep(), the substantive part of the sleep operation is wrapped in a Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS block, allowing other threads to continue to execute while the current one sleeps. You can also test this with a simple python program:

import time
from threading import Thread

class worker(Thread):
    def run(self):
        for x in xrange(0,11):
            print x
            time.sleep(1)

class waiter(Thread):
    def run(self):
        for x in xrange(100,103):
            print x
            time.sleep(5)

def run():
    worker().start()
    waiter().start()

Which will print:

>>> thread_test.run()
0
100
>>> 1
2
3
4
5
101
6
7
8
9
10
102

回答 1

它只会休眠线程,除非您的应用程序只有一个线程,在这种情况下,它将休眠线程并有效地进程。

睡眠中的python文档未指定此内容,因此我当然可以理解混淆!

http://docs.python.org/2/library/time.html

It will just sleep the thread except in the case where your application has only a single thread, in which case it will sleep the thread and effectively the process as well.

The python documentation on sleep doesn’t specify this however, so I can certainly understand the confusion!

http://docs.python.org/2/library/time.html


回答 2

只是线程。

Just the thread.


回答 3

该线程将阻塞,但是该进程仍然有效。

在单线程应用程序中,这意味着您在睡眠时一切都被阻止了。在多线程应用程序中,只有您显式“睡眠”的线程将被阻塞,其他线程仍在进程中运行。

The thread will block, but the process is still alive.

In a single threaded application, this means everything is blocked while you sleep. In a multithreaded application, only the thread you explicitly ‘sleep’ will block and the other threads still run within the process.


回答 4

只有线程,除非您的进程具有单个线程。

Only the thread unless your process has a single thread.


回答 5

进程本身无法运行。关于执行,进程只是线程的容器。这意味着您根本无法暂停该过程。它根本不适用于过程。

Process is not runnable by itself. In regard to execution, process is just a container for threads. Meaning you can’t pause the process at all. It is simply not applicable to process.


回答 6

如果它在同一线程中执行,则它将阻塞一个线程,如果不是从主代码中执行,则它将阻塞该线程

it blocks a thread if it is executed in the same thread not if it is executed from the main code


如何使我的Python程序休眠50毫秒?

问题:如何使我的Python程序休眠50毫秒?

如何使我的Python程序休眠50毫秒?

How do I get my Python program to sleep for 50 milliseconds?


回答 0

from time import sleep
sleep(0.05)

参考

from time import sleep
sleep(0.05)

Reference


回答 1

需要注意的是,如果你依靠睡眠服用正好 50毫秒,你不会得到那个。就是这样。

Note that if you rely on sleep taking exactly 50 ms, you won’t get that. It will just be about it.


回答 2

import time
time.sleep(50 / 1000)
import time
time.sleep(50 / 1000)

回答 3

也可以使用pyautogui作为

import pyautogui
pyautogui._autoPause(0.05,False)

如果first不为None,则它将暂停第一个arg秒,在此示例中:0.05秒

如果first为None,第二arg为True,则它将休眠以设置的全局暂停设置

pyautogui.PAUSE = int

如果您想知道原因,请参见源代码:

def _autoPause(pause, _pause):
    """If `pause` is not `None`, then sleep for `pause` seconds.
    If `_pause` is `True`, then sleep for `PAUSE` seconds (the global pause setting).

    This function is called at the end of all of PyAutoGUI's mouse and keyboard functions. Normally, `_pause`
    is set to `True` to add a short sleep so that the user can engage the failsafe. By default, this sleep
    is as long as `PAUSE` settings. However, this can be override by setting `pause`, in which case the sleep
    is as long as `pause` seconds.
    """
    if pause is not None:
        time.sleep(pause)
    elif _pause:
        assert isinstance(PAUSE, int) or isinstance(PAUSE, float)
        time.sleep(PAUSE)

can also using pyautogui as

import pyautogui
pyautogui._autoPause(0.05,False)

if first is not None, then it will pause for first arg second, in this example:0.05 sec

if first is None, and second arg is True, then it will sleep for global pause setting which is set with

pyautogui.PAUSE = int

if you are wondering the reason, see the source code:

def _autoPause(pause, _pause):
    """If `pause` is not `None`, then sleep for `pause` seconds.
    If `_pause` is `True`, then sleep for `PAUSE` seconds (the global pause setting).

    This function is called at the end of all of PyAutoGUI's mouse and keyboard functions. Normally, `_pause`
    is set to `True` to add a short sleep so that the user can engage the failsafe. By default, this sleep
    is as long as `PAUSE` settings. However, this can be override by setting `pause`, in which case the sleep
    is as long as `pause` seconds.
    """
    if pause is not None:
        time.sleep(pause)
    elif _pause:
        assert isinstance(PAUSE, int) or isinstance(PAUSE, float)
        time.sleep(PAUSE)

回答 4

您也可以使用Timer()功能来实现。

码:

from threading import Timer

def hello():
  print("Hello")

t = Timer(0.05, hello)
t.start()  # After 0.05 seconds, "Hello" will be printed

You can also do it by using Timer() function.

Code:

from threading import Timer

def hello():
  print("Hello")

t = Timer(0.05, hello)
t.start()  # After 0.05 seconds, "Hello" will be printed