2

我有两个任务需要在后台同时以不同的线程优先级执行:

  1. 持续收集和处理陀螺运动数据(高优先级)

    gyroQueue = [[NSOperationQueue alloc] init];
    
    [self.motionManager startDeviceMotionUpdatesToQueue:gyroQueue withHandler:^(CMDeviceMotion *motion, NSError *error){
        [self processMotion:motion withError:error];
    }];
    
  2. 有时在不干扰运动更新的情况下处理图像(转换、裁剪、调整大小等 = 1-2 秒)(非常低的优先级)

    imageProcessingQueue = [[NSOperationQueue alloc] init];
    
    [imageProcessingQueue addOperationWithBlock:^{
        [self processImage:[UIImage imageWithData:imageData]];
    }];
    

编辑:这是我最初所拥有的(而不是阻止操作),它仍然阻止运动更新:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(processImage:) object:[UIImage imageWithData:imageData]];
[operation setThreadPriority:0.0];
[operation setQueuePriority:0.0];
[imageProcessingQueue addOperation:operation];

似乎这两个任务都在同一个后台线程上执行(由于 NSOperationQueue 的性质?),并且图像的处理会阻止 gyroQueue 更新,直到它完成,这是我试图避免的。

如何使用 NSOperationQueue 生成两个单独的线程,并相应地分配veryHigh 和veryLow 优先级?

编辑:这个问题仍然悬而未决,我正在使用 Travor Harmon 的图像调整大小功能来调整图像大小。有人可以确认它是否是线程安全的吗?

4

2 回答 2

0

我已经为这个问题找到了一个解决方案(或可靠的解决方法):

我没有使用 将 deviceMotion 更新路由到队列startDeviceMotionUpdatesToQueue,而是创建了一个 CADisplayLink 计时器,它不会干扰其他后台队列 - 虽然它与屏幕刷新率匹配,但它的本质是最高优先级:

[self.motionManager startDeviceMotionUpdates];

gyroTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(processMotion)];
[gyroTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
于 2013-04-07T22:25:00.687 回答
0

我认为在这里您可以尝试仅创建一个操作队列并尝试根据需要设置每个操作的优先级。如果你只使用一个队列,线程优先级会更有效,让你的头脑以更清晰的方式思考(毕竟这只是建议。)

- (void)setThreadPriority:(double)priority

您指定的值映射到操作系统的优先级值。指定的线程优先级仅在执行操作的 main 方法时应用于线程。在执行操作的完成块时不应用它。对于您创建自己的线程的并发操作,您必须在自定义启动方法中自己设置线程优先级,并在操作完成时重置原始优先级。

来自苹果的文档。

Operation queues usually provide the threads used to run their operations. In Mac OS X v10.6 and later, operation queues use the libdispatch library (also known as Grand Central Dispatch) to initiate the execution of their operations. As a result, operations are always executed on a separate thread, regardless of whether they are designated as concurrent or non-concurrent operations. In iOS 4 and later, operation queues use Grand Central Dispatch to execute operations.

于 2012-07-18T05:32:25.910 回答