线程还是异步?

时间:2008-09-14 13:56:15

标签: multithreading language-agnostic

如何使您的应用程序成为多线程? 你使用异步功能吗? 或者你产生一个新的线程? 我认为asynch函数已经产生了一个线程,所以如果你的工作只是做一些文件读取,懒惰而只是在一个线程上产生你的工作只会“浪费”资源...... 那么在使用线程或异步函数时是否有某种设计?

5 个答案:

答案 0 :(得分:7)

如果你在谈论.Net,那么别忘了ThreadPool。线程池也是异步函数经常使用的。产生大量线程实际上可能会损害您的性能。线程池旨在产生足够的线程来以最快的速度完成工作。因此,除非线程池不能满足您的需求,否则请使用线程池而不是刷新自己的线程。

PS:请留意微软的Parallel Extensions

答案 1 :(得分:6)

如果你开始产生大量的线程,产生线程只会浪费资源,一个或两个额外的线程不会影响平台的性能,实际上系统目前有超过70个线程供我使用,而msn正在使用32个(我真的不知道一个信使如何使用那么多线程,特别是当它最小化而不是真的做任何事情时......)

使用产生线程的好时机是需要花费很长时间的事情,但是你需要继续做其他事情。

例如说计算需要30秒。最好的办法是为计算生成一个新线程,以便您可以继续更新屏幕,并处理任何用户输入,因为如果您的应用程序冻结,直到完成计算,用户就会讨厌它。

另一方面,创建线程来做几乎可以立即完成的事情几乎是没有意义的,因为创建(甚至只是使用线程池将工作传递给现有线程)的开销将高于仅仅执行首先是工作。

有时你可以将你的应用分成几个独立的部分,这些部分在自己的线程中运行。例如,在游戏中,更新/物理等可能是一个线程,而grahpics是另一个,声音/音乐是第三个,而网络是另一个。这里的问题是你真的必须考虑这些部分将如何相互作用,否则你可能会有更糟糕的表现,看似“随机”发生的错误,或者甚至可能陷入僵局。

答案 2 :(得分:2)

我将第二个Fire Lancer's回答 - 创建自己的线程是处理大型任务或处理任务的绝佳方式,否则这些任务会“阻塞”同步应用程序的其余部分,但是< / strong>您必须清楚地了解必须以明确定义线程任务的方式解决和开发的问题,并限制其工作范围。

对于我最近工作的一个例子 - 一个Java控制台应用程序定期运行,通过屏幕抓取网址,使用DOM解析文档,提取数据并将其存储在数据库中来捕获数据。

作为单线程应用程序,正如您所料,它占用了一个年龄,平均每秒大约1个url,50kb页面。还不错,但当你扩展到需要批量处理数千个网址时,这是不行的。

对应用程序进行概要分析表明,大多数情况下活动线程处于空闲状态 - 它正在等待I / O操作 - 打开远程URL的套接字,打开与数据库的连接等。就是这种情况,可以通过多线程轻松改进。重写为多线程,只需5个线程而不是一个,即使在单个核心CPU上,也可以将吞吐量提高20倍以上。

在此示例中,每个“worker”线程都明确限于它所做的 - 打开远程URL远程,解析数据,将其存储在db中。所有“高级”处理 - 生成要解析的URL列表,确定下一个,处理错误,所有都保留在主线程的控制之下。

答案 3 :(得分:0)

使用线程可以让您更多地考虑应用程序需要线程的方式,并且从长远来看可以更轻松地改善/控制您的性能。
异步方法使用起来更快,但它们有点神奇 - 许多事情都会使它们成为可能 - 所以很可能在某些时候你会需要一些他们无法给你的东西。然后,您可以尝试滚动一些自定义线程代码 这一切都取决于你的需求。

答案 4 :(得分:0)

答案是“它取决于”。

这取决于你想要达到的目标。我将假设你的目标是提高性能。

最简单的解决方案是找到另一种方法来改善您的表现。运行一个分析器。寻找热点。减少不必要的IO。

下一个解决方案是将程序分解为多个进程,每个进程都可以在自己的地址空间中运行。这是最简单的,因为个别进程不可能互相搞乱。

下一个解决方案是使用线程。此时你正在打开一个主要的蠕虫病毒,所以从小开始,只有多线程代码的关键路径。

下一个解决方案是使用asynch IO。通常只建议人们编写一些负载很重的服务器,即便如此,我宁愿重新使用一个现有的框架来抽象出细节,例如: C ++框架ICE,或java下的EJB服务器。

请注意,这些解决方案中的每一个都有多个子解决方案 - 有不同的线程品种和不同类型的异步IO,每个都有不同的性能特征,但同样,通常最好让框架为您处理。