淘先锋技术网

首页 1 2 3 4 5 6 7

我正在编写一个队列处理应用程序,它使用线程来等待并响应要传递给应用程序的队列消息。 对于应用程序的主要部分,它只需要保持活动状态。 对于代码示例,例如:

1

2while True:

pass

要么

1

2while True:

time.sleep(1)

哪一个对系统的影响最小? 什么是什么都不做,但保持python应用程序运行?

正确的答案是根本不进行轮询I / O. 例如,请参阅select()调用,操作系统将在此处休眠,直到准备好读取内容为止。

好吧,在线程的情况下,他们使用阻塞TCP连接等待消息。 它只是我关注的主要线程,它除了处理命令行选项,读取配置和线程踢之外什么都不做。

我认为time.sleep()将减少系统的开销。使用pass将导致循环立即重新评估并固定CPU,而使用time.sleep将允许执行暂时中止。

编辑:只是为了证明这一点,如果你启动python解释器并运行:

1

2

3>>> while True:

... pass

...

您可以观看Python立即开始吃掉90-100%的CPU,而不是:

1

2

3

4>>> import time

>>> while True:

... time.sleep(1)

...

甚至几乎没有在Activity Monitor上注册(在这里使用OS X,但每个平台应该是相同的)。

谢谢,我认为就是这样,但我一直看到文件传递。

为什么睡觉?你不想睡觉,你想等待线程完成。

所以

1

2

3# store the threads you start in a your_threads list, then

for a_thread in your_threads:

a_thread.join()

请参阅:thread.join

不过,我不希望线程完成。这是一个没有结束的过程。这个逻辑是否仍然适用?

当然逻辑仍然适用。你可以避免浪费甚至几个周期来进行"循环"睡眠。

这似乎不起作用,因为线程不应该终止进程终止,超时可能在概念上总是先出现,或者我错过了什么?

@Crad - 什么超时?主要线索是永远等待孩子们。这就是主线程的作用。

@Crad:在我的示例代码中,我没有指定任何超时,因此连接将永远等待。你有理由自己指定一个吗?

如果您正在寻找一种简短的零CPU方式来循环直到KeyboardInterrupt,您可以使用:

1

2

3from threading import Event

Event().wait()

注意:由于存在错误,这仅适用于Python 3.2+。此外,它似乎无法在Windows上工作。因此,while True: sleep(1)可能是更好的选择。

对于某些背景,Event对象通常用于等待长时间运行的进程完成:

1

2

3

4

5

6

7

8

9

10def do_task():

sleep(10)

print('Task complete.')

event.set()

event = Event()

Thread(do_task).start()

event.wait()

print('Continuing...')

哪个印刷品:

1

2Task complete.

Continuing...

请注意,这适用于Linux和Mac,但在Windows上,KeyboardInterrupt不会中断event.wait()。如果指定了等待超时,则异常将在超时结束时引发,但如果没有给出,则event.wait()将永久阻塞。在Windows上,SIGINT将中断睡眠,这样就可以实现更好的实现。我在任何地方都没有看到这个,但它一直是我的测试经验(Python 3.7)。我在这里找到了一个相关的主题:stackoverflow.com/questions/39545612/

@joshstaiger有趣。我已经更新了帖子。我确实发现由于Python 2中的一个错误,它没有用,但我绝不会猜到它在Windows中无法使用3.2+。

你没有为你真正做的事情提供太多的背景,但是可能会使用Queue而不是显式的忙等待循环?如果没有,我会认为sleep会更好,因为我相信它会消耗更少的CPU(正如其他人已经注意到的那样)。

[根据以下评论中的其他信息进行编辑。]

也许这是显而易见的,但无论如何,在你从阻塞套接字读取信息的情况下,你可以做的是从套接字读取一个线程并将适当格式化的消息发布到Queue,然后让你剩下的"worker"线程从该队列中读取;然后,工作人员将阻止从队列中读取而不需要pass,也不需要sleep。

感谢Queue上的提示看起来很方便,在这个应用程序中,我使用阻塞套接字来侦听来自AMQP代理(在单独的线程中)的消息,并在收到时对它们采取行动。

@Crad:然后使用select在套接字上等待,类似于队列的工作方式。不要使用繁忙的等待或轮询。

我一直看到/听说使用睡眠是更好的方法。使用sleep将使您的Python解释器的CPU使用率不再过时。

signal.pause()是另一种解决方案,请参阅https://docs.python.org/3/library/signal.html#signal.pause

Cause the process to sleep until a signal is received; the appropriate handler will then be called. Returns nothing. Not on Windows. (See the Unix man page signal(2).)

在Python中使用sleep运行方法作为后台线程

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34import threading

import time

class ThreadingExample(object):

""" Threading example class

The run() method will be started and it will run in the background

until the application exits.

"""

def __init__(self, interval=1):

""" Constructor

:type interval: int

:param interval: Check interval, in seconds

"""

self.interval = interval

thread = threading.Thread(target=self.run, args=())

thread.daemon = True # Daemonize thread

thread.start() # Start the execution

def run(self):

""" Method that runs forever"""

while True:

# Do something

print('Doing something imporant in the background')

time.sleep(self.interval)

example = ThreadingExample()

time.sleep(3)

print('Checkpoint')

time.sleep(2)

print('Bye')