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

velocirabbit:

我对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的工作。

主线程基本上总是只在等待用户按下键来访问菜单的不同部分。这似乎是asyncio的理想之选,但同样,我不确定。

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

什么时候应该在Python中使用类?

什么时候应该在Java中使用接口?

什么时候应该在ExecutorService上使用CompletionService?

什么时候应该在Go中使用`new`?

什么时候应该在C ++中使用“朋友”?

什么时候应该在元组上使用记录?

什么时候应该在QListView上使用QListWidget?

我什么时候应该在lodash.merge上使用icepick.merge

我应该在什么时候使用哪种进程间通信(ipc)机制?

为什么我的异步Jest测试应该在什么时候不失败?

什么时候(不应该)我应该在Android上测试UI组件?

我什么时候应该在TypeScript中使用“ var”,“ let”和“ const”

什么时候应该在Python中使用'assert'?

什么时候应该使用Array,什么时候应该在Scala中使用ArrayBuffer?

我应该在SQL查询中使用什么代替“减号”运算符以提高性能?

什么时候以及为什么我们应该在角度使用View Encapsulation

我什么时候应该在StratifiedKFold中洗牌

为什么我的if语句应该在什么时候不评估为假?

我什么时候应该在Windows上使用3rd party卸载程序?

什么时候应该在mongo中使用$ limit?

什么时候应该在Python中使用split()?

我什么时候应该在 Robot 测试框架中为变量使用引号

我们什么时候应该在 CodeIgniter 中使用核心?

什么时候应该在 Android 中使用 KeyChain?

我什么时候应该在子进程上使用 Python-git

我什么时候应该在 DialogProc 上返回 TRUE 和 FALSE

我什么时候应该在 '$this' 上使用 'self'?

我什么时候应该在 constexpr 模板函数中使用 if constexpr 与常规 if 并置?

什么时候应该在 .NET 中使用 SemaphoreSlim?