【发布时间】:2019-09-13 10:31:26
【问题描述】:
我有一个性能敏感的代码,实时处理视频播放的帧。我在这里有一些可以并行化的工作,因为它是一个性能敏感的代码,其中延迟是我决定使用NSThread 而不是GCD 的关键。
我需要什么:我需要NSThread,它将在某个时间段安排一些工作。线程完成工作后,它会进入休眠状态,直到新的工作到来。
不幸的是,互联网上没有太多关于NSThread 使用正确技术的信息,所以我根据我设法找到的信息位组装了我的例程。
您可以在上面找到整个工作流程:
1) 初始化我的NSThread。此代码仅按预期启动一次。
_myThread = [[NSThread alloc] initWithTarget:self selector:@selector(_backgroundMethod) object:nil];
_myThread.threadPriority = 0.8; //max priority is 1.0. Let's try at 0.8 and see how it performs
[_myThread start];
2)_backgroundMethod代码:
- (void)_backgroundMethod
{
NSLog(@"Starting the thread...");
[NSTimer scheduledTimerWithTimeInterval:FLT_MAX target:self selector:@selector(doNothing:) userInfo:nil repeats:YES];
BOOL done = false;
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
do {
[runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!done);
}
- (void)doNothing:(NSTimer *)sender { }
3) 当线程有事情要处理时,我会进行下一次调用:
[self performSelector:@selector(_doSomeCalculation) onThread:_myThread withObject:nil waitUntilDone:NO];
调用下一个方法:
- (void) _doSomeCalculation
{
//do some work here
}
所以我的问题是:
1) 当我初始化NSThread 时,我传递了一个选择器。该选择器的目的是什么?据我了解,这个选择器的唯一目的是控制线程的 RunLoop,我不应该在这里做任何计算。因此,我正在使用无限计时器让NSRunLoop 保持活力,而无需不断运行while 循环。这是正确的方法吗?
2) 如果我可以在 NSThread 初始化阶段传递的选择器中进行计算 - 我如何在不使用 performSelector 的情况下向 NSRunLoop 发出信号以执行一个循环?我认为我不应该使用performSelector 传递完全相同的方法,因为它会一团糟,对吧?
我已经阅读了 Apple 提供的大量信息,但所有这些信息几乎都是理论上的,而提供的那些代码示例让我更加困惑..
任何澄清将不胜感激。提前致谢!
编辑:
还有一个问题 - 如何为我的线程计算所需的 stackSize?有什么技术可以做到吗?
【问题讨论】:
-
错误的决定。使用
GCD。它旨在“杀死”NSThread。它有你需要的一切。你现在只是在重新发明 GCD。您可以直接使用GCD或Objective-C 的包装器NSOperationQueue -
您好!以下是 Apple 在文章
Migrating Away from Threads-It is important to remember that queues are not a panacea for replacing threads. The asynchronous programming model offered by queues is appropriate in situations where latency is not an issue. Even though queues offer ways to configure the execution priority of tasks in the queue, higher execution priorities do not guarantee the execution of tasks at specific times. Therefore, threads are still a more appropriate choice in cases where you need minimal latency, such as in audio and video playback.中对NSThread的评价 -
所以我想指出,我决定尝试
NSThread,因为在这种特殊情况下,GCD存在某些问题——比如延迟会随着时间的推移而降低,并且不同设备上的性能不均衡。我需要更多地控制我的任务的执行方式并学习如何正确地完成它 -
我认为苹果在这里的意思是你在线程中执行简单的后续工作:从输入中获取数据,处理它,将其放入输出。当您创建运行循环并执行选择器时,不是这样的调度机制。执行选择器也比直接调用函数需要更多时间,如果延迟如此重要,你应该考虑一下。
-
我将不得不与@Cy-4AH 合作。要么使用 GCD 在单个队列上完成所有工作,要么使用
NSThread而不为每个进程运行循环。看来你不止一个。在这两种情况下,当您需要在此线程中完成的工作太多而无法处理时,您都会产生延迟。打开的线程数量会增加,或者前一个任务还没有完成,新的任务将被安排,从而产生延迟。后者基本上是GCD应该做的。
标签: ios objective-c multithreading nsthread nsrunloop