进程以及线程说明
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用于将代码块封装成NSOperationNSInvocationOperation * 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]; }
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- C#线程间不能调用剪切板的解决方法
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- 简单对比C#程序中的单线程与多线程设计
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- C++使用CriticalSection实现线程同步实例
- 基于C++实现的线程休眠代码
- VB读取线程、句柄及写入内存的API代码实例
- C#网络编程基础之进程和线程详解
- C#通过Semaphore类控制线程队列的方法
- C#多线程处理多个队列数据的方法