Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 带信号量的优先级控制_Objective C_Swift_Grand Central Dispatch - Fatal编程技术网

Objective c 带信号量的优先级控制

Objective c 带信号量的优先级控制,objective-c,swift,grand-central-dispatch,Objective C,Swift,Grand Central Dispatch,假设我有一个信号量来控制对调度队列的访问。 在调度调度队列上的块之前,我等待信号量(dispatch\u semaphore\u wait) dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER) dispatch_async(queue){ //do work ; dispatch_semaphore_signal(semaphore); } 假设我的工作在几个不同的地方等待。有些“工作”比另一些“工作”优先级更高 有没有办法控制下一

假设我有一个信号量来控制对调度队列的访问。 在调度调度队列上的块之前,我等待信号量(dispatch\u semaphore\u wait)

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER)
dispatch_async(queue){ //do work ; dispatch_semaphore_signal(semaphore); }
假设我的工作在几个不同的地方等待。有些“工作”比另一些“工作”优先级更高

有没有办法控制下一步将安排哪些“工作”

附加信息:对于我来说,使用没有信号量的串行队列不是一个选项,因为“工作”由它自己的带有几个块的队列组成。必须运行所有工作队列,或者不运行任何工作队列。没有工作队列可以同时运行。除了优先级控制之外,所有这些都可以正常工作

编辑:(回应Jeremy,从评论中删除)

好的,假设你有一个设备/文件/任何类似打印机的东西。打印作业由多个函数调用/块(打印标题、打印图形、打印文本等)组成,并在事务中分组。将这些块放在串行队列中。每个事务一个队列

但是,您可以有多个打印作业/事务。来自不同打印作业/事务的块不能混合。那么,如何确保事务队列运行其所有作业,并且在另一个队列完成之前不启动事务队列?(我不是在打印,只是以此为例)

信号量用于调节有限资源的使用。


我试图弄清楚的下一步是如何在一个事务之前运行另一个事务。

您在这里误用了API。您不应该使用信号量来控制调度队列的内容

如果要序列化队列上块的执行,请使用串行队列而不是并发队列

如果正在排队的不同块具有不同的优先级,则应使用OS X 10.10和iOS 8.0中添加的QOS机制表示不同的优先级。如果需要在较旧的系统上运行,则可以使用不同优先级的全局并发队列进行适当的工作。除此之外,对旧系统没有太多控制


此外,信号量本质上不利于优先级继承,因为系统无法确定谁将向信号量发送信号,因此您很容易陷入这样一种情况:高优先级线程将被阻塞很长时间,等待低优先级线程向信号量发信号。这称为优先级反转。

每个事务都应该是队列中的单个块。您可以在队列的单个块中执行事务的所有较小块。如果您正在做大量不涉及资源的工作,那么您就是在阻塞队列。假设您必须从数据库中提取1M行,计算内容(长时间工作),然后将答案返回数据库。在后台处理数字时,您不希望阻塞数据库队列。这样,您就不应该在db访问队列上进行处理。从db队列上的db获取数据,然后在后台队列上运行处理,然后在db队列上添加结果。假设您尝试进行读/写访问,您应该使用一个并发队列,使用写入屏障。让我们退一步:我有一个资源队列,每个事务有一个单独的队列。在每个事务队列上,我都会将逻辑分组在一起的计划块。(transaction.begin{}.then{}.then{}.done{}类似于函数式编程中的承诺)事务队列的目标队列被设置为资源队列。因为数据库需要维护数据完整性,所以事务应该从头到尾运行。包含多个事务(包括后台工作)的作业项有其自己的后台队列。作业项可以并发运行,事务不能。只需为事务创建一个块,直接执行其他每个块。然后将这一块(事务)排队。如果事务修改了资源并且队列是并发的,请确保使用屏障。您没有理由为每个事务创建队列。只需在单个块中执行所有事务。在一个事务之前运行另一个事务正是串行队列的用途。您需要使每个事务成为队列上的一个块。放弃使用信号量,因为这很容易导致优先级反转。好的,我会用谷歌搜索优先级反转并重新考虑。