线程还是异步的?
如何使应用程序成为多线程?
我们使用异步功能吗?
还是生成新线程?
我认为,异步函数已经在生成一个线程,因此,如果工作只是在读取文件,变得懒惰并且仅在线程上生成工作,那只会"浪费"资源...
那么在使用线程或者异步函数时是否有某种设计?
解决方案
回答
如果我们正在谈论.Net,请不要忘记ThreadPool。线程池也是异步函数经常使用的线程。产生大量线程实际上会损害性能。线程池被设计为仅产生足够多的线程以最快的速度完成工作。因此,请使用线程池而不是浪费自己的线程,除非线程池不能满足需求。
PS:请密切注意Microsoft的Parallel Extensions
回答
线程的使用使我们可以更多地考虑应用程序需要线程化的方式,并且从长远来看可以使提高/控制性能变得更加容易。
异步方法的使用速度更快,但是它们有些不可思议,因此发生了很多事情,因此有可能在某些时候我们将需要一些它们无法提供的东西。然后,我们可以尝试投放一些自定义线程代码。
这完全取决于需求。
回答
生成线程只会浪费资源,如果我们开始产生大量的线程,一个或者两个额外的线程不会影响平台性能,infact System目前为我提供了70多个线程,而msn正在使用32(我确实有不知道一个Messenger可以如何使用那么多线程,特别是当它最小化并且什么都不做的时候...)
生成线程的好时机通常是花费很长时间,但是我们需要继续做其他事情。
例如说计算将花费30秒。最好的办法是产生一个新线程进行计算,以便我们可以继续更新屏幕并处理任何用户输入,因为如果应用程序冻结直到完成计算,用户就会讨厌它。
另一方面,创建线程以执行几乎可以立即完成的操作几乎是没有意义的,因为创建(或者什至只是使用线程池将工作传递给现有线程)的开销将比仅执行线程中的工作要高。第一名。
有时,我们可以将应用程序分成几个独立的部分,它们分别在各自的线程中运行。例如,在游戏中,更新/物理等可能是一个线程,而grahpics是另一个线程,声音/音乐是第三线程,而网络是另一个线程。这里的问题是我们真的必须考虑这些部分将如何交互,否则性能可能会下降,错误似乎是"随机地"发生的,甚至可能死锁。
回答
我将第二讲Fire Lancer的答案,即创建自己的线程是一种处理大型任务或者处理可能会"阻塞"同步应用程序其余部分的任务的绝妙方法,但是我们必须对问题有一个清晰的了解我们必须以明确定义线程任务并限制其作用范围的方式进行解决和开发。
例如,我最近在一个Java控制台应用程序上工作,该应用程序定期运行,以捕获数据,方法是实质上是对网址进行屏幕抓取,使用DOM解析文档,提取数据并将其存储在数据库中。
如我们所料,作为单线程应用程序,它花了很长时间,对于50kb的页面,平均每秒需要大约1 url。还不错,但是当我们扩展到需要批量处理成千上万个URL时,那就不好了。
对应用程序进行性能分析表明,在大多数情况下,活动线程处于空闲状态时,它正在等待I / O操作,以打开到远程URL的套接字,打开与数据库的连接等。通过这种方式可以很容易地改善这种情况多线程。重写为多线程并且仅使用5个线程而不是1个线程,即使在单核cpu上,吞吐量也提高了20倍以上。
在此示例中,每个"工作者"线程都明确地限于其打开远程URL,解析数据并将其存储在db中的操作。所有"高级"处理都会生成要解析的url列表,然后计算出接下来要处理的错误,所有这些操作都保留在主线程的控制之下。
回答
答案是"取决于"。
这取决于我们要实现的目标。我将假设目标是提高性能。
最简单的解决方案是找到另一种提高性能的方法。运行探查器。寻找热点。减少不必要的IO。
下一个解决方案是将程序分成多个进程,每个进程都可以在各自的地址空间中运行。这是最简单的,因为各个进程之间不会相互混淆。
下一个解决方案是使用线程。此时,我们将打开大量的蠕虫病毒,因此从小处开始,并且仅对线程的关键路径进行多线程处理。
下一个解决方案是使用异步IO。通常只推荐给编写一些负载很重的服务器的人使用,即使那样,我还是想重用抽象了细节的现有框架之一,例如C ++框架ICE或者Java下的EJB服务器。
请注意,这些解决方案中的每一个都有多个子解决方案,分别有不同种类的线程和不同种类的异步IO,每种都有不同的性能特征,但是通常最好还是让框架为我们处理。