这个问题与网络服务器上有大量休眠 python 线程可能会或可能不会引起的性能损失有关。
背景:我正在使用 django/satchmo 实现一个在线商店。要求是延迟付款。客户可以预订产品并允许第三方在以后付款(通过随机且唯一的 URL)。
为了处理取消预订的项目,我创建了一个线程,该线程将在预订时间内休眠,然后在唤醒时删除预订/将产品标记为已售出。它看起来像这样:
#Reserves a product when it is placed in the cart
def reserve_cart_product(product):
log.debug("Reserving %s" % product.name)
product.active = False
product.featured = False
product.save()
from threading import Timer
Timer(CART_RESERVE_TIME, check_reservation, (product,)).start()
我在剔除过期后的唯一 URL 时使用了相同的技术,只是 Timer 休眠的时间更长(通常为 5 天)。
那么,我向您提出的问题如下:
大量休眠线程会严重影响性能吗?是否有更好的技术来安排 future 某个时间的一次性事件?如果可能的话,我想把它保存在 python 中;不通过 sys
调用 at
或 cron
。
该站点的访问量不是很高;每周订购产品的(慷慨)上限约为 100。结合购物车预订,这可能意味着任何时候都有 100 多个休眠线程。我会后悔以这种方式安排任务吗?
谢谢
最佳答案
我看不出为什么这不起作用。 Timer 的底层代码(在 threading.py 中)仅使用 time.sleep。一旦它等待了一段时间,它基本上运行一个循环 time.sleep(0.05) 这应该导致 CPU 使用率基本上为 0%,即使有数百个线程。这是一个简单的示例,我注意到 python 进程的 cpu 使用率为 0%:
import threading
def nothing():
pass
def testThreads():
timers = [threading.Timer(10.0, nothing) for _ in xrange(881)]
print "Starting threads."
map(threading.Thread.start, timers)
print "Joining threads."
map(threading.Thread.join, timers)
print "Done."
if __name__ == "__main__":
testThreads()
真正的问题是您实际上可能无法启动太多线程。在我的 64 位 4GB 系统上,在出现错误之前我只能启动 881 个线程。但是,如果您真的只有几百个,我无法想象它不会起作用。
关于Python:对休眠线程的惩罚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2178563/