}
在上面的代码里,线程主体入口点是PosixThreadMainRoutine,通过pthread_create创建线程,在创建线程前初始化及配置线程属性pthread_attr_init/pthread_attr_setdetachstate
注:基于C语言的应用程序,常用的线程间通讯包括使用端口(ports),条件(conditions)和共享内存(shared memory)
3,使用NSObject创建线程
[myObj performSelectorInBackground:@selector(doSomething) withObject:nil];参照NSThread方法创建线程
4,使用其他技术创建线程
唯一一个可以考虑使用的是多处理
服务(Multiprocessing Services),它本身就是在 POSIX 线程上执行
5,在Cocoa程序里使用POSIX线程,需要注意的问题
A,Cocoa框架的保护
对于多线程应用程序,Cocoa框架使用锁和其他同步方式保证代码的正确使用。但是为了避免因为这些锁造成的单线程下的性能损失,Cocoa框架直到应用程序创建NSThread类生成它的第一个新线程的时候才创建这些锁。如果仅用POSIX创建新的线程,那么Cocoa框架将不会自动创建这些保护同步的锁。这样有可能因为这些造成Cocoa崩溃。解决办法:在创建第一个新线程之前,使用NSThread类生成一个线程,并让他立刻退出。这样保证Cocoa框架所需要的锁到位。
B,混合POSIX和Cocoa的锁
在同一应用程序里面可以混合使用POSIX和Cocoa的锁,因为Cocoa的锁和条件对象基本上只是封装POSIX的互斥体和条件。但是两者不能交叉使用,Cocoa的NSLock调用POSIX创建的mutex对象,反之依然
三,配置线程属性
线程属性主要包括线程的堆栈大小,本地存储,线程的脱离状态(detached),线程的优先级
1,配置线程的堆栈大小
A,Cocoa线程,只有通过New NSThread类的方法创建的线程才能配置线程的堆栈大小
[myThread setStackSize];
B,POSIX线程,创建一个限的pthread_attr_t数据结构,使用pthread_attr_setstacksize函数设置线程堆栈大小
2,配置线程本地存储---每个线程都维护一个键-值的字典结构,如何设置和访问这个结构呢?
A,Cocoa线程,NSMutableDictionary *mDict = [[NSThread currentThread] threadDictionary];
B,POSIX线程,通过pthread_setspecific设置这个结构,通过pthread_getspicific访问这个结构
3,设置线程的脱离状态
脱离线程(Detach Thread)---线程完成后,系统自动释放它所占用的内存空间
可连接线程(Joinable Thread)---一线程完成后,不回收可连接线程的资源
在应用程序退出时,脱离线程可以立即被中断,而可连接线程则不可以。每个可连接
线程必须在进程被允许可以退出的时候被连接。所以当线程处于周期性工作而不允许被中断的时
候,比如保存数据到硬盘,可连接线程是最佳选择。
如果你想要创建可连接线程,唯一的办法是使用 POSIX 线程。POSIX 默认创建的
线程是可连接的。通过pthread_attr_setdetachstate函数设置是否脱离属性
4,线程的优先级
A,Cocoa线程,[NSThread setThreadPriority];设置线程的优先级
B,POSIX线程,pthread_setschedparam函数实现优先级设置
注:高低线程交互时,要注意因为低线程的饥饿状态造成的阻塞,造成性能瓶颈,影响应用程序性能。
四,线程主体入口函数
在线程主体入口函数里面,主要做三个工作:
1,创建一个自动释放池(Autorelease pool),注意:要经常主动清理自动释放池里面的内存,提高线程的内存空间
2,设置异常处理
添加try/catch模块,捕获任何未知的异常,并提供适当的响应
3,设置一个run loop
对于需要动态处理到来的任务请求的线程,需要给线程添加一个run loop
五,中断线程
中断线程要注意的是,尽力保证线程从主体入口函数里面退出,这样能够保证线程的资源被自动释放。
- (void)threadMainRoutine
{
Bool moreWorkToDo = YES;
Bool exitNow = NO;
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
// Add the exitNow BOOL to the thread dictionary
NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
[threadDict setValue:[NSNumber numberWithBool:exitNow] forKey:@"ThreadShouldExitNow"];
// install an input method
[self myInstallCustomInputSource];
while(moreWorkToDo && !exitNow)
{
// Do one chunk of a larger body of work here
// change the value of the moreWorkToDo Boolean when Done
// Run the run loop but timeout immediately if the input source isn't waiting to fire
[runLoop runUntilDoneDate:[NSDate date]];
// check the see if an input source handle changed the exitNow value.
exitNow = [[threadDict valueForKey:@"ThreadShouldExitNow"] boolValue];
}
}