iOS多线程开发(二)---线程管理

线程管理

线程管理包括创建,配置,退出三部分。主要包括创建线程的成本,线程创建,线程属性配置,线程主体入口函数编写,线程中断等

一,线程创建成本

1,为辅助线程分配的堆栈空间大小,便于系统和进程管理,以及为函数参数和局部变量分配空间

A,内核数据结构(kernel data structures)---大约1KB,This memory is used to store the thread data structures and attributes, much of which is allocated as wired memory and therefore cannot  be

B,堆栈空间(Stack Space)---512 KB(secondary threads)/8 MB (Mac OS X main thread)/1 MB (iOS main thread) ,The minimum allowed stack size for secondary threads is 16 KB and the stack size must be a multiple of 4 KB. The space for this memory is set aside in your process space at thread creation time, but the actual pages associated with that memory are not created until they are need

2,创建线程需要的时间成本---大约90ms,创建时间依赖于处理器的负载,计算速度,和可用的系统和程序空间i

二,创建线程

创建线程需要做三部分工作:主体入口点,可用线程(用以启动被创建的线程),线程的属性配置。创建线程有很多方法,比如NSThread,POSIX,NSObject,及其他方法(Multiprocessing Services)等

1,使用NSThread创建线程

A,[NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];

线程的主体入口点是myThreadMainMethod,可用线程是self存在的线程,不过这个线程的属性不能在线程创建前配置,只能在线程内配置

B,创建一个新的NSThread实例,然后调用他的start方法启动线程

NSThread  *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadMainMethod) withObject:nil];

[myThread start]; // Actually create the thread

线程主体入口是myThreadMainMethod,可用线程是self存在的线程,线程属性可以在创建一个新的NSThread实例之后,start方法调用之前设置

注:通过NSThread创建的线程,主要通过performSelector:onThread:withObject:withUntilDone方法进行线程间通信比较便捷的方法之一。

2,使用POSIX创建线程

A,Creating a thread in C

#include <assert.h>

#include <pthread.h>

void* PosixThreadMainRoutine(void* data)

{

// DO Some Work here

......

return NULL

}

void  LaunchThread()

{

// Create the thread using POSIX routines.

pthread_attr_t attr;

pthread_t  posixThreadID;

int returnVal;

returnVal =  pthread_attr_init(&attr);

assert(!returnVal);

returnVal = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

assert(!returnVal);

int threadError = pthread_create(&posixThreadID, &attr, &PosixThreadMainRoutine, NULL);

returnVal = pthread_attr_destroy(&attr);

assert(!returnVal);

if (threadError != 0)

{

// Report an error.

}

}

在上面的代码里,线程主体入口点是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];

}

}

时间: 2024-10-12 14:02:01

iOS多线程开发(二)---线程管理的相关文章

iOS多线程开发——GCD的使用与多线程开发浅析(二)

对于iOS多线程开发,我们时刻处于学习之中,在看书中,看文档中,项目开发中,都可以去提高自己.最近刚看完了<Objective-C高级编程 iOS与OS X多线程和内存管理>这本书后,对多线程有了更为深入的理解,故在此做一个总结与记录.这本书我已经上传至网盘  https://pan.baidu.com/s/1c2fX3EC ,这本书是iOS开发者必读的书之一,写得很不错,欢迎大家下载阅读.书的封面如下,故也称狮子书: . (1)多线程会遇到的问题 . 多线程会出现什么问题呢?当多个线程对同一

iOS多线程开发小demo5 线程间的通信

// DYFViewController.m // 623-06-线程间的通信 // // Created by dyf on 14-6-23. // Copyright (c) 2014年 ___FULLUSERNAME___. All rights reserved. // #import "DYFViewController.h" @interface DYFViewController () @property (weak, nonatomic) IBOutlet UIImag

iOS多线程开发小demo4,线程的同步问题

// DYFViewController.m // 623-05-线程同步问题 // // Created by dyf on 14-6-23. // Copyright (c) 2014年 ___FULLUSERNAME___. All rights reserved. // #import "DYFViewController.h" @interface DYFViewController () @property (nonatomic, assign) int leftCount

iOS多线程开发小demo3,线程的状态

// Created by dyf on 14-6-23. // Copyright (c) 2014年 ___FULLUSERNAME___. All rights reserved. // #import "DYFViewController.h" @interface DYFViewController () @property (nonatomic, strong) NSThread *thread; @end @implementation DYFViewController

iOS多线程开发之深入GCD

iOS多线程开发之深入GCD 一.前言 在以前的一些系列博客中,对iOS中线程的管理做了总结,其中涵盖了GCD的相关基础知识:http://my.oschina.net/u/2340880/blog/417746.那里面将GCD的线程管理能力,列队组能力,通过信号和消息控制程序流程的能力都有介绍,这里,我们继续深入GCD的功能,通过GCD来处理一些逻辑更加复杂的代码功能. 二.延时追加任务 当我们在程序中处理延时任务的时候,我们一般会通过两种方式,一种是通过定时器进行延时执行,另外一种是通过如下

IOS多线程开发

本文转载至 http://blog.csdn.net/davidsph/article/details/8171607 IOS的多线程,一般分为三种方式: 1,Thread;2, Cocoa operations;3, Grand Central Dispatch (GCD) (iOS4 才开始支持) 下面简单说明一下: 1:NSThread   创建方式主要有两种: [NSThread detachNewThreadSelector:@selector(myThreadMainMethod:)

ios 多线程开发(三)Run Loops

Run loops是线程相关的一些基本东西.一个run loop是一个处理消息的循环.用来处理计划任务或者收到的事件.run loop的作用是在有事做的时候保持线程繁忙,没事的时候让线程挂起. Run loop的管理并不是完全自动的.你仍然需要设计代码来在合适的时候启动run loop来相应事件.Cocoa和Core Foundation都提供了run loop对象来配置和管理run loop.程序并不需要创建这些对象,每个线程,包括主线程都有一个对应的run loop对象.只有非主线程需要明确

iOS多线程开发——NSThread浅析

在IOS开发中,多线程的实现方式主要有三种,NSThread.NSOperation和GCD,我前面博客中对NSOperation和GCD有了较为详细的实现,可以参考<iOS多线程开发--NSOperation/NSOperationQueue浅析><iOS多线程开发--GCD的使用与多线程开发浅析>.以及对于多线程中的同步异步,并行串行等概念,我在<GCD实践--串行队列/并发队列与iOS多线程详解>中也有较为详细的讲解.为了学习的完整性,今天我们主要从代码层面来实现

转载 多线程开发时线程局部变量的使用

多线程开发时线程局部变量的使用 http://blog.csdn.net/zsxxsz/article/details/6284759 2011-03-28 22:37197人阅读评论(0)收藏举报 一.概述 现在多核时代多线程开发越来越重要了,多线程相比于多进程有诸多优势(当然也有诸多劣势).在早期C的库中,有许多函数是线程不安全的,因为内 部用到了静态变量,比如:char *strtok(char *s, const char *delim); 该函数内部就有一个静态指针,如果多个线程同时调

iOS多线程开发小demo

首先演示一下主线程的阻塞 // DYFViewController.m // 623-01-阻塞多线程 // // Created by dyf on 14-6-23. // Copyright (c) 2014年 ___FULLUSERNAME___. All rights reserved. // #import "DYFViewController.h" @interface DYFViewController () @end @implementation DYFViewCon