有没有一种方法可以进入Cocoa多线程模式而不创建虚假的NSThread?

7

苹果线程指南表示:

对于多线程应用程序,Cocoa框架使用锁和其他形式的内部同步来确保它们的正确行为。然而,为了防止这些锁在单线程情况下降低性能,Cocoa直到应用程序使用NSThread类生成其第一个新线程才创建它们。如果您仅使用POSIX线程例程生成线程,则Cocoa不会收到它需要了解您的应用程序现在是多线程的通知。当发生这种情况时,涉及Cocoa框架的操作可能会破坏或崩溃应用程序。

要让Cocoa知道您打算使用多个线程,您所需做的就是使用NSThread类生成单个线程,然后立即退出该线程。您的线程入口点不需要执行任何操作。仅仅使用NSThread生成线程的行为就足以确保Cocoa框架需要的锁被放置。

在我的iOS应用程序中,我从C++代码开始几个pthread。为确保应用程序按照上述文档的要求运行正确,我创建了一个不做任何事情的虚拟NSThread。我不喜欢创建这样无用的代码(通常是“WTF”,当您首次阅读它时),我想避免这样做。有没有更好的方法将我的应用程序置于多线程模式?


能否提供创建NSThread的代码?您是否在线程上调用了“start”方法? - pzearfoss
1个回答

3
如果有,那它不是公开的,可能不稳定。
如果你的代码出现了 WTF,请重新命名和调整代码,以使其更加合理。由于你还需要一个带有虚拟选择器的虚拟对象,因此你可以添加一个类似于 CocoaMultithreading 的丢弃类,然后发送一个 +beginMultithreading 消息:
@interface CocoaMultithreading : NSObject
+ (void)beginMultithreading;
@end

int
main(void) {
    [CocoaMultithreading beginMultithreading];
    /* now do whatever you want */
    return EXIT_SUCCESS;
}

@implementation CocoaMultithreading
+ (void)dummyThread:(id)unused
{
    (void)unused;
}

+ (void)beginMultithreading
{
    [NSThread detachNewThreadSelector:@selector(dummyThread:)
            toTarget:self withObject:nil];
}
@end

这应该足够明确了。

预计时间: Alexander Staubo指出,自从OS X 10.5/iOS 2.0以来,您可以直接调用NSThread上的-start方法,因此在Cocoa多线程上启用最简单的方法如下:

void XXXActivateCocoaMultithreading(void) { [[NSThread new] start]; }

然后,在你的main函数中:
XXXActivateCocoaMultithreading();

这也是明确的,但要简洁得多。 (XXX在那里提醒您添加非静态函数的前缀。由于静态函数经常会在某个时候变为非静态函数,从一开始就给它们都加上前缀是一个好习惯。)


实际上,看起来这已经足够了:[[NSThread new] start];。之后,[NSThread isMultiThreaded] 返回 YES - Alexander Staubo
@AlexanderStaubo 很不错!-start在OS X 10.5中被添加到了NSThread中,并且从2.0版本开始就一直存在于iOS中,所以不用担心。我唯一的担忧可能是当涉及到股票NSThread上的main做什么时,可能会利用未定义行为。我在NSThread文档中看到了有关“默认main”的提到,但没有实际讨论如果您没有在子类中覆盖它或设置目标和选择器,它将做什么。如果有人对此感到满意,那么这绝对是最简单的方法,尽管他们仍应添加一些内容来解释为什么随机启动了虚拟线程。 - Jeremy W. Sherman
看起来 NSThread 简单地忽略不存在的选择器。在早期的 ObjC 中,这会向 stderr 发出警告,在 ObjC 2.0 中似乎是静默的。(真希望 Xcode 自带核心框架源代码。试图反汇编 Foundation 库让我一无所获。) - Alexander Staubo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接