2011-01-28 45 views
1

我有以下查询,我需要某人请帮助我。我新来的消息队列,最近开始看Kestrel消息队列。 据我所知,线程和消息队列都用于应用程序中的并发,所以使用消息队列优于多线程?为什么消息队列使用了多线程?

请帮 谢谢。

回答

2

消息队列允许您在程序之外进行通信。

这使您可以将生产者与消费者分离。您可以将工作分散到多个流程和机器上,您可以独立管理/升级/移动这些程序。

消息队列通常还包含一个或多个代理,负责分发消息并确保消息在发生不良情况时不会丢失(例如,您的程序崩溃,您升级了其中一个程序等)

消息队列也可能在一个程序,在这种情况下,它往往只是一个工厂从生产线交换/队列数据给消费者线程进行异步处理内部使用。

2

其实,一方便另一方便。消息队列是一个很好且简单的多线程模式:当您有一个控制线程(通常但不一定是应用程序的主线程)和一个(通常是循环的)工作线程池时,消息队列是便于控制线程的最简单方法池。

例如,开始处理相对繁重的任务,您提交相应的消息放入队列中。如果你有更多的消息,比你现在可以处理更多的消息,你的队列增长,如果更少,反之亦然。当你的消息队列为空时,你的线程会休眠(通常是通过锁定在互斥量下)。

那么,有什么比较:消息队列是多线程的一部分,因此他们在多线程的一些更复杂的情况下使用。

1

对比消息队列和其他并发原语(比如信号量,互斥量,条件变量等)是更有意义的。它们都可以用于线程的存在,尽管消息传递也常用于非线程,线程上下文(例如进程间通信),而其他线程往往局限于线程间通信和同步。

简而言之,消息传递在大脑上更容易。详细...

消息传递通过将东西从一个代理发送到另一个代理。通常不需要协调对数据的访问。代理收到消息后,通常可以认为它具有对该数据的非限定访问权限。

的“线程”风格的作品给予所有代理开放式涂满访问共享数据,但要求他们精心组织通过其原语的访问。如果一个代理人行为不当,这个过程就会被破坏,所有地狱都会崩溃。消息传递往往将问题局限于行为不端行为人及其队列,并且由于代理通常是自包含的并且通常以顺序或状态机的方式进行编程,所以它们往往不像常规线程代码那样经常或者神秘地行为不端。

1

创建线程是昂贵的,每一个线程同时是“活”将添加一定量的开销,即使线程被阻塞,等待事情发生。如果程序Foo有1,000个任务需要执行,并且不关心按照什么顺序完成,那么可能创建1,000个线程并让每个线程执行一个任务,但这种方法效率不高。第二种方法是让一个线程按顺序执行所有1,000个任务。如果系统中有其他进程可以使用Foo没有使用的任何CPU时间,则后一种方法将是有效的(并且很可能是最优的),但是如果没有足够的工作来保持所有CPU忙,CPU就会浪费一段时间闲置。在大多数情况下,让CPU闲置一秒钟就像花费一秒钟的CPU时间一样昂贵(主要的例外是当人们试图最小化电能消耗时,因为空闲的CPU可能消耗的功率远远小于忙碌的CPU )。

在大多数情况下,最好的策略是在这两种方法之间妥协:让一些线程(比如10个)开始执行前10个任务。每当线程完成一项任务时,让它开始工作,直到所有任务完成。使用这种方法,与线程相关的开销将减少99%,唯一的额外成本将是尚未开始的任务队列。由于队列条目比线程便宜得多(可能不到成本的1%,可能还不到0.01%),这可能代表了非常大的节省。

使用作业队列而不是线程的一个主要问题是,如果某些作业无法完成,直到列表中的作业稍后才运行,则系统可能会死锁,因为稍后的任务将不会运行,直到早期的任务已经完成。如果每个任务都被赋予了一个单独的线程,那么就不会发生这个问题,因为与后面的任务相关的线程最终会完成并因此让更早的任务继续。事实上,更早的任务被阻止,CPU时间可用于运行更晚的任务。

相关问题