调度队列绑定到确切的线程



im 开发一个应用程序,它使用一些框架通过 openGL 绘制 3D 工作人员。这个框架要求我从完全相同的线程调用draw()方法。

因此,我创建了一个串行DispatchQueue,并在其中启动了CADisplayLink,以60FPS的速度调用draw()。我必须从这个确切的线程调用的其他方法很少,例如start()stop().这使队列成为我的完美解决方案。

如您所知,DispathQueue 不能保证在同一线程上执行每个任务。这对我来说压力很大,因为它可能会破坏我的应用程序。

我真的不喜欢创建 NSThread 并在其上实现我自己的队列的想法。

有没有办法将调度队列绑定到确切的线程?也许NSOperationQueue可以绑定?

正如 Apple 文档所说:

在向应用程序添加并发性时,调度队列比线程具有多个优势。最直接的优点是工作队列编程模型的简单性。对于线程,您必须为要执行的工作以及线程本身的创建和管理编写代码。调度队列可让您专注于实际想要执行的工作,而不必担心线程的创建和管理。相反,系统会为您处理所有线程的创建和管理。优点是系统能够比任何单个应用程序更有效地管理线程。系统可以根据可用资源和当前系统条件动态扩展线程数。此外,与自己创建线程相比,系统通常能够更快地开始运行任务。

简而言之,您要么使用调度队列,简单地创建它们并将工作发送给它们,要么使用NSThreadNSRunLoop,创建它们,设置它们,向它们发送工作,并可能停止它们。

详细地:

NSThread/NSRunLoop

创造:

self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadMainRoutine) object:nil];
[self.thread start];

启动/管理:

- (void)threadMainRoutine
{
// Set the runLoop variable, to signal this thread is alive
self.runLoop = [NSRunLoop currentRunLoop];
// Add a fake Mach port to the Run Loop, to avoid useless iterations of the main loop when the
//  thread is just started (at this time there are no events added to the run loop, so it will
//  exit immediately from its run() method)
[self.runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
//--- Thread main loop
while (thread_KeepRunning)
{
// Run the run loop. This function returns immediately if the RunLoop has nothing to do.
//  NOTE: THIS STATEMENT:
//      [self.runLoop run];
//      DOES NOT WORK, although it is equivalent to CFRunLoopRun();
CFRunLoopRun();
}
// Unset the runLoop variable, to signal this thread is about to exit
self.runLoop = nil;
}

添加要对其执行的工作:

[self performSelector:@selector(mySelector:) onThread:myThread withObject:myObject waitUntilDone:YES];

关闭:

- (void)stop
{
if (self.thread) {
while (self.thread.isExecuting) {
thread_KeepRunning = NO;
CFRunLoopStop([self.runLoop getCFRunLoop]);
[NSThread sleepForTimeInterval:0.1f];
}
}
self.runLoop = nil;
self.thread = nil;
}

调度队列

创造:

dispatch_queue_t myQueue = dispatch_queue_create("My Queue", DISPATCH_QUEUE_SERIAL);

开始:

dispatch_resume(myQueue);

添加要对其执行的工作:

dispatch_async(myQueue, (void)^ {
// put the work into this block
});

关闭:

dispatch_suspend(myQueue);
myQueue = nil;

此外,苹果文档说

由于 Grand Central Dispatch 管理您提供的任务与运行这些任务的线程之间的关系,因此通常应避免从任务代码调用 POSIX 线程例程。如果出于某种原因确实需要调用它们,则应非常小心调用哪些例程

所以:如果你使用调度队列,不要弄乱线程。

相关内容

  • 没有找到相关文章

最新更新