您的位置:首页 > 移动开发 > IOS开发

进程以及线程说明

2016-06-17 19:06 603 查看

线程和进程

进程:当一个程序进入内存运行后,就变成了一个进程,进程是系统进行资源分配和调度的一个独立单位。

进程特性:

1. 独立性 :系统独立存在的尸体,拥有自己独立的资源和私有的地址空间,在没有进程本身允许的情况下,用户进程不可以访问其他进程的地址空间。

2. 动态性 :程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合,进程中加入了时间的概念,进程具有自己的生命周期和各种不同的状态。

3. 并发性:多个进程可在单个处理器上并发执行,多个进程之间不会相互影响。

线程:线程是独立运行的,一个线程可以创建撤销另一个线程,同一个进程可以多个线程并发,它们共享进程的内存、文件句柄、和其他每个进程应有的状态。

多线程有点:

1. 多进程不共享内存,但多线程共享内存

2. 创建进程需要为该进程重新分配系统资源,但创建线程的代价小得多,使得实现多任务并发效率更高

3. ios提供了多种多线程实现方式,从而简化了多线程编程

实现多线程编程的三种技术

1. NSThread

2. NSOperation和NSOperationQueue

3. GCD(Grand Central Dispatch)

NSThread

创建和启动线程

-(id) initWithTarget:(id)target selector:(SEL)selector object:(id)arg

创建一个新线程对象,设置target的selector方法,传入arg参数,调用start方法启动

+(void) detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)arg

创建并启动新线程

@implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
//创建线程对象,设定方法对象为self,方法为run,参数为nil
NSThread * thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
//启动线程
[thread start];
// 创建线程,设定方法对象为self,方法为run,参数为nil,并启动
[NSThread detachNewThreadSelector:self toTarget:@selector(run) withObject:nil];
}
-(void)run
{
NSLog(@"==%@==",[NSThread currentThread]);
}


NSThread还有

+currentThread方法返回当前执行的线程对象

setName:方法来为线程设置名字

name属性返回线程的名字

[self performSelectorOnMainThread:@selector(action) withObject:object waitUntilDone:YES]方法会返回UI线程执行方法体

终止子线程的三种方式:

线程执行体方法执行完成,线程正常结束

线程执行过程中出现错误

调用NSThread的exit方法来终止当前正在执行的线程

IOS中没有提供方法来终止某个子线程,cancel方法只是改变该线程的状态,但由此也可以通过改变子线程的状态使该子线程自调用[NSThread exit]方法来终止线程

@implementation ViewController
NSThread * thread;
-(void)viewDidLoad
{
[super viewDidLoad];
//创建线程对象,设定方法对象为self,方法为run,参数为nil
thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
//启动线程
[thread start];
}
-(void)run
{
if([NSThread currentThread].isCancelled)
{
//终止当前线程
[NSThread exit];
}
NSLog(@"==%@==",[NSThread currentThread]);
}
//该方法设定thread对象的isCancelled属性为NO,由此当thread执行run方法时,会由于if条件符合而执行[NSThread exit]而终止线程
-(IBAction)cancelThread:(id)sender
{
//设定thread对象的isCancelled属性为NO
[thread cancel];
}


线程睡眠以及线程的状态

+(void)sleepUntilDate:(NSDate*)date

线程暂停到date代表的时间,并进入阻塞状态

+(void)sleepForTimeInterval:(NSTimeInterval*)time

线程暂停time秒,病进入阻塞状态,例如[NSThread sleepForTimeInterval:0.5]

线程使用start方法后,不是立即进入运行状态,而是出于就绪状态,当系统调度线程后才会进入运行状态,如果希望线程立即运行则可使用[NSThread sleepForTimeInterval:0.001]方法即可。

线程安全

可还用@synchronized、NSLock、NSCondition来实现同步锁,同步锁同一时间只允许一个线程执行锁中内容,其中NSCondition还可以通过-wait、-waitUntilDate:(NSDate*)date、-single、boardcast来对其他线程进行影响

GCD

GCD多线程步骤:创建队列,然后将任务提交给队列

创建队列

获取当前执行代码所在的队列:

dispatch_queue_t queue = dispatch_get_current_queue();


创建队列获取默认的全局并发队列:

/*第一个参数可指定不同优先级DISPATCH_QUEUE_PRIORITY_HIGH(2)、DISPATCH_QUEUE_PRIORITY_DEFAULT(0)、DISPATCH_QUEUE_PRIORITY_LOW(-2)、DISPATCH_QUEUE_PRIORITY_BACKGROUND,第二个参数暂无用,可设置为0 */
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);


获取系统主线程关联的串行队列

dispatch_queue_t queue = dispatch_get_main_queue();


创建串行队列

/* 第一个参数为字符串,指定为标签,第二个参数可设定为串行(DISPATCH_QUEUE_SERIAL)或者并行(DISPATCH_QUEUE_CONCURRENT) */
dispatch_queue_t queue = dispatch_queue_create("myjava.queue", DISPATCH_QUEUE_SERIAL);


创建并发队列

dispatch_queue_t queue = dispatch_queue_create("myjava.queue",DISPATCH_QUEUE_CONCURRENT);


获取指定队列的字符串标签

const char * dispatch_queue_get_label(dispatch_queue_t queue);


提交任务

//将代码块以异步方式提交给指定队列
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block)

//将函数以异步方式提交给指定队列
void dispatch_async_f(dispatch_queue_t queue, void * context, dispatch_function_t work)

//将代码块以同步方式提交给指定队列
void dispatch_sync(dispatch_queue_t queue, dispatch_bloack_t block)

//将函数以同步方式提交给指定队列
void dispatch_sync_f(dispatch_queue_t queue, void * context, dispatch_function_t work)

//将代码块以异步方式提交给指定队列,并在when指定的时间点执行
void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block)

//将函数以异步方式提交给指定队列,并在when指定的时间点执行
void dispatch_after_f(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block)

//将代码块以异步方式提交给指定队列,线程池可多次重复执行该代码块
void dispatch_apply(size_t iterations, dispatch_queue_t queue, void(^block)(size_t))

//将函数以异步方式提交给指定队列,线程池可多次重复执行该函数
void dispatch_apply_f(size_t iterations, dispatch_queue_t queue, void * context, void(* work)(void*, size_t))

/*将代码块提交给指定队列,该队列的线程池控制在应用的某个生命周期内仅执行一次函数,其中predicate参数是一个纸箱dispatch_once_t(本质是long型整数)的变量指针,用于判断该函数是否已经执行过*/
void dispatch_once(dispatch_once_t * predicate, dispatch_block_t block)


NSOperation与NSOperationQueue

多线程实现步骤:创建NSOperationQueue对象,创建NSOperation的子类NSInvocationOperation或者NSBlockOperation对象,将NSInvocationOperation或者NSBlockOperation对象提交给NSOperationQueue对象执行

NSOperationQueue

+currentQueue 返回执行当前NSOperation的NSOperationQueue队列

+mainQueue 返回系统主线程的NSOperationQueue队列

-(void)addOperation:(NSOperation*)operation 将operation添加到NSOperationQueue队列中

-(void)addOperation:(NSArray*)ops waiUntilFinished:(BOOL)wait 将NSArray中包含的所有NSOperation添加到NSOperationQueue队列中,wait参数为YES时,会阻塞当前线程,直到NSArray添加完成,wait参数为NO时,立即返回,NSArray会以异步的方式添加,不阻塞当前线程

-operations 只读属性,返回该NSOperationQueue管理的所有NSOperation

-operationCount 只读属性,返回该NSOperationQueue管理的NSOperation的数量

-cancelAllOperations 取消NSOperationQueue中所有正在排队和执行的NSOperation

-waitUntilAllOperationsAreFinished 阻塞当前线程,直到该NSOperationQueue种所有排队和执行的NSOperation执行完成才接触阻塞

-(NSInteger)maxConcurrentOperationCount 返回该NSOperationQueue队列最大支持的并发NSOperation数量

-setMaxConcurrentOperationCount:(NSInteger)count 设置该NSOperationQueue队列最大支持的并发NSOperation数量

-setSuspended:(BOOL)suspend 设置NSOperationQueue是否暂停调度正在排队的NSOperation

-(BOOL)isSuspended 返回NSOperationQueue是否已经暂停调度正在排队的NSOperation

NSInvocationOperation和NSBlockOperation

两者均为NSOperation的子类,NSInvocationOperation用于将特定对象的特定方法封装成NSOperation,NSBlockOperation用于将代码块封装成NSOperation

NSInvocationOperation * iOperation = [[NSinvocationOperation alloc] initWithTarget:self selector:@selector(downloadImageFromURL:) object:URL];

NSBlockOperation * bOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"--执行代码块--");
}];


亦可自定义类来继承NSOperation,重构init方法,重写main方法。

DownloadImageOperation.h

#import <Foundaiton/Foundation.h>

@interface DownloadImageOperation: NSOperation

@property (nonatomic, strong) NSUTL * url;
@property (nonatomic, weak) UIImageView* imageView;

-(id)initWithURL:(NSURL*)url imageView:(UIImageView*)iv;

@end


DownloadImageOperation.m

@import "DownloadImageOperation.h"

@implementation DownloadImageOperation

-(id)initWithURL:(NSURL*)url imageView:(UIImageView*)iv
{
self = [super init];
if(self)
{
_url = url;
_imageView = imageView;
}
return self;
}

-(void)main
{
//获取image
NSData * data = [[NSData alloc] initWithContentOfURL:self.url];
UIImage * image = [[UIImage alloc] initWithData:data];
if(image != nil)
{
//在主线程中执行updateUI:方法
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
}
}

-(void)updateUI:(UIImage*)image
{
self.imaeView.image = image;
}
@end


ViewController.m

@implementation ViewController

NSOperationQueue * queue

-(void)viewDidLoad
{
[super viewDidLoad];
queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 10;
}

-(IBAction)clicked:(id)sender
{
NSURL * url = [NSURL URLWithString:@"http://ab.com/image.jpg"];
DownloadImageOperation * operation = [[DownloadImageOperation alloc] initWithURL:url imageView:self.iv];
[queue addOperation:operation];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线程 ios