我什么时候应该在常规线程上使用asyncio,为什么?它可以提高性能吗? - python

我对Python中的多线程有基本的了解,甚至对asyncio也有较基本的了解。

我目前正在编写一个基于Curses的小型程序(最终将使用完整的GUI,但这是另一个故事),该程序处理主线程中的UI和用户IO,然后有两个其他守护程序线程(每个线程都有自己的守护程序)排队/工人从队列中得到东西的方法):

  • 一个watcher线程,监视是否发生基于时间的和有条件的(例如,张贴到留言板,收到的消息等)事件,然后将所需的任务放入...
  • 另一个(worker)守护程序线程的队列,然后完成它们。
  • 这三个线程都连续并发运行,这使我想到了一些问题:

  • worker线程的队列(或更一般地说,任何线程的队列)为空时,应该停止它,直到再次执行某件事为止,还是可以让它连续运行?当并发线程除了观察队列之外什么都不做时,它们是否占用了大量处理能力?
  • 两个线程的队列应该合并吗?由于watcher线程连续运行单个方法,所以我猜worker线程将能够从watcher线程放入的单个队列中提取任务。
  • 我不认为这无关紧要,因为我不是多处理人员,但是此设置是否会以任何方式受Python的GIL(我相信仍然存在于3.4中)的影响?
  • watcher线程是否应该像这样连续运行?据我了解,如果我错了,请纠正我,asyncio应该用于基于事件的多线程,这似乎与我要执行的操作有关。
  • 主线程基本上总是在等待用户按下键来访问菜单的不同部分。这似乎是asyncio的理想之选,但我不确定。
  • 谢谢!

    参考方案

    当工作线程的队列(或更普遍地说,任何线程的队列)为空时,是否应该停止它直到再次执行某项操作,还是可以让它连续运行?当并发线程除了观察队列之外什么都不做时,它们是否占用了大量处理能力?

    您应该只对queue.get()使用阻塞调用。这将使线程在I / O上处于阻塞状态,这意味着将释放GIL,并且将不使用任何处理能力(或至少非常少量)。不要在while循环中使用非阻塞获取,因为这将需要更多的CPU唤醒。

    两个线程的队列应该合并吗?由于观察程序线程正在连续运行单个方法,因此我猜工作线程将能够从观察程序线程放入的单个队列中提取任务。

    如果观察者所做的只是将事情从一个队列中拉出来,然后立即放入另一个队列中,由单个工作人员使用,那么这听起来像是不必要的开销-您也可以直接在工作人员中使用它。不过,我尚不清楚情况是否如此-观察者是从队列中消费,还是只是将物品放入一个队列中?如果它从队列中消费,那么谁来填充东西呢?

    我认为这并不重要,因为我不是多处理人员,但是此设置是否会以任何方式受到Python的GIL(我相信仍然存在于3.4中)的影响?

    是的,这受GIL的影响。一次只有一个线程可以运行Python字节码,因此不会获得真正的并行性,除非线程正在运行I / O(释放GIL)。如果您的工作线程正在执行CPU绑定的活动,则应尽可能考虑通过multiprocessing在单独的进程中运行它。

    观察者线程是否应该像这样连续运行?据我了解,如果我错了,请纠正我,asyncio应该用于基于事件的多线程,这似乎与我要执行的操作有关。

    很难说,因为我不完全了解“连续运行”的含义。它连续在做什么?如果它花费大部分时间在queue上睡眠或阻塞,那很好-这两件事都会释放GIL。如果它一直在进行实际工作,那将需要GIL,因此会降低应用程序中其他线程的性能(假设它们试图同时工作)。 asyncio设计用于受I / O约束的程序,因此可以使用异步I / O在单个线程中运行。听起来您的程序可能很适合此操作,具体取决于您的worker正在做什么。

    主线程基本上总是只在等待用户按下键来访问菜单的不同部分。 这似乎是一种情况,对于来说,异步是完美的,但是,我不确定。

    几乎所有等待I / O的程序都可能适合asyncio-但前提是您能找到一个使curses发挥作用的库(或最终选择的任何其他GUI库)。大多数GUI框架都带有自己的事件循环,该事件循环将与asyncio冲突。您将需要使用一个库,该库可以使GUI的事件循环与asyncio的事件循环很好地配合使用。您还需要确保可以找到应用程序使用的任何其他基于同步I / O的库的asyncio兼容版本(例如,数据库驱动程序)。

    就是说,从基于线程的程序切换到基于asyncio的程序,您不太可能看到任何类型的性能改进。它的性能可能大致相同。由于您只处理3个线程,因此在它们之间进行上下文切换的开销不是很明显,因此从该单线程异步I / O方法切换不会产生太大差异。 asyncio将帮助您避免线程同步的复杂性(如果这是您的应用程序存在的问题-尚不清楚),并且至少在理论上,如果您的应用程序可能需要大量线程,则伸缩性会更好,但这似乎不是案子。我认为对您来说,基本上取决于您希望使用哪种样式编写代码(假设您可以找到所需的所有与asyncio兼容的库)。

    Python:如何停止多线程的numpy? - python

    我知道这似乎是一个荒谬的问题,但是我必须在与部门中其他人共享的计算服务器上定期运行作业,当我开始10个作业时,我真的希望它只占用10个核心而不是更多;我不在乎每次运行一个内核所需的时间是否更长:我只是不想让它侵犯其他人的领土,这将需要我放弃工作等等。我只想拥有10个核心,仅此而已。更具体地说,我在基于Python 2.7.3和numpy 1.6.1的Redh…

    Python GPU资源利用 - python

    我有一个Python脚本在某些深度学习模型上运行推理。有什么办法可以找出GPU资源的利用率水平?例如,使用着色器,float16乘法器等。我似乎在网上找不到太多有关这些GPU资源的文档。谢谢! 参考方案 您可以尝试在像Renderdoc这样的GPU分析器中运行pyxthon应用程序。它将分析您的跑步情况。您将能够获得有关已使用资源,已用缓冲区,不同渲染状态上…

    python asyncio run_forever或True - python

    我应该在代码中替换while True(不使用asyncio)还是应该使用asyncio事件循环来实现相同的结果。目前,我正在处理某种与“ zeromq”连接的“工作者”,接收一些数据,然后对外部工具(服务器)执行一些请求(http)。一切都以普通的阻塞IO编写。使用asyncio事件循环摆脱while True: ...是否有意义?将来可能会用asynci…

    Python:图像处理可产生皱纹纸效果 - python

    也许很难描述我的问题。我正在寻找Python中的算法,以在带有某些文本的白色图像上创建皱纹纸效果。我的第一个尝试是在带有文字的图像上添加一些真实的皱纹纸图像(具有透明度)。看起来不错,但副作用是文本没有真正起皱。所以我正在寻找更好的解决方案,有什么想法吗?谢谢 参考方案 除了使用透明性之外,假设您有两张相同尺寸的图像,一张在皱纹纸上明亮,一张在白色背景上有深…

    Python uuid4,如何限制唯一字符的长度 - python

    在Python中,我正在使用uuid4()方法创建唯一的字符集。但是我找不到将其限制为10或8个字符的方法。有什么办法吗?uuid4()ffc69c1b-9d87-4c19-8dac-c09ca857e3fc谢谢。 参考方案 尝试:x = uuid4() str(x)[:8] 输出:"ffc69c1b" Is there a way to…