如果我想在后台运行任务,“dispatch_get_global_queue”队列如何工作?

时间:2014-01-14 19:32:30

标签: ios objective-c multithreading grand-central-dispatch nsoperation

在选择要运行dispatch_async的队列时,会提到很多dispatch_get_global_queue。这是一个特殊的后台队列,它将任务委托给某个线程吗?它几乎是一个单身人士吗?

因此,如果我总是将这个队列用于我的dispatch_async调用,那么该队列是否会变满并且必须等待其他事情才能启动,或者是否可以将其他任务分配给不同的线程?

我想我有点困惑,因为当我选择NSOperation的队列时,我可以选择[NSOperationQueue mainQueue]主线程的队列,这似乎是{{1}的同义词但是我的印象是dispatch_get_main_queue的背景队列必须是NSOperation的单独实例,但GCD有一个背景队列的单例? (NSOperationQueue

此外 - 愚蠢的问题,但想确保 - 如果我将一个任务放入队列,队列被分配给一个线程,对吧?如果任务足够大,它不会在多个线程上拆分它,是吗?

1 个答案:

答案 0 :(得分:5)

  

选择运行dispatch_async的队列时,   dispatch_get_global_queue被提到了很多。这是一个特别的   将任务委托给某个线程的后台队列?

某个线程?编号dispatch_get_global_queue为您检索所请求的相对优先级的全局队列。 dispatch_get_global_queue返回的所有队列都是并发的,并且可以由系统自行决定将工作分派给许多不同的线程。这个机制是一个实现细节,作为API的使用者对您来说是不透明的。

在实践中,并且存在过度简化风险的风险,每个优先级都有一个全局队列,在撰写本文时,根据我的经验,每个人都会在任何时候将调度工作发送到0和64个线程。

  

几乎是一个单身人士吗?

严格来说没有,但你可以把它们看作是每个优先级只有一个单身人士的单身人士。

  

因此,如果我总是将该队列用于我的dispatch_async调用,那么就是这样   队列满了,必须等待事情在另一个之前完成   一个人可以开始,还是可以将其他任务分配给不同的线程?

它可以变满。实际上,如果您正在使一个全局并发队列(即同时在飞行中同时具有相同优先级的64个以上后台任务)饱和,那么您的设计可能很糟糕。 (有关队列宽度限制的更多详细信息,请参阅this answer

  

我想我有点困惑,因为当我选择队列时   一个NSOperation,我可以选择主线程的队列   [NSOperationQueue mainQueue],这似乎是同义词   dispatch_get_main_queue

它们不是严格意义上的同义词。尽管NSOperationQueue使用了GCD,但也存在一些重要的差异。例如,在主运行循环的单次传递中,只会执行一个排队到+[NSOperationQueue mainQueue]的操作,而提交给dispatch_get_main_queue的多个块可能会在单个运行循环传递上执行。这对你来说可能无关紧要,但严格来说,它们不是同一回事。

  

但我的印象背景   NSOperation的队列必须是单独的实例   NSOperationQueue,但GCD有一个背景队列的单例吗?   (dispatch_get_global_queue)

简而言之,是的。这听起来像是在混淆GCD和NSOperationQueueNSOperationQueue不仅仅是GCD的“琐碎包装”,它也是它自己的东西。它在GCD之上实现的事实对你来说并不重要。 NSOperationQueue是一个具有明确可设置宽度的任务队列,您可以创建“随意”的实例。您可以根据自己的喜好制作尽可能多的。在某些时候,NSOperationQueue的所有实例在执行NSOperations时都会从与您的进程的其余部分(包括GCD)相同的系统资源池中提取资源,所以是的,那里有一些交互,但它们对你来说是不透明的。

  

此外 - 愚蠢的问题,但想确保 - 如果我提出任务   在队列中,队列被分配给一个线程,对吧?如果任务是   足够大,它不会在多个线程上拆分它,是吗?

单个任务只能在单个线程上执行。没有一些神奇的方法,系统必须将整体任务“拆分”为子任务。那是你的工作。关于您的具体措辞,队列不是“分配给一个线程”,任务是。要执行的队列中的下一个任务可能在完全不同的线程上执行。