多线程编程

来源:互联网 发布:js this用法 编辑:程序博客网 时间:2024/06/11 15:57

多线程的几种方式

PThread

NSThread

CGD (Grand Center Dispatch)

NSOperation (NSInvaocationOperation / NSBlockOperation)

1.PThread

POSIX Thread(Portable Operation System Interface) 可移植的操作系统的接⼝口 ⼀一套通⽤用的多线程API;基于C语⾔言的接⼝口;难度较⼤大;⼏几乎不⽤用。

1.1使用PThread创建线程

步骤⼀:导⼊入pthread.h 头⽂文件

#impoet <pthread.h>

步骤二:创建⼦子线程对象pthread_t

pthread_t thread;

步骤三:提供线程执⾏行函数

void *task(void *data){......}

步骤四:创建⼦子线程,并执⾏行任务

pthread_create(&thread,                        NULL, //线程属性 task,                        task,   //函数指针                         NULL  //传给函数指针的参数 );

NSThread

优势:基于OC接⼝口,使⽤用⽅方便
缺点:⼿手动管理线程的⽣生命周期

2.1使用NSThread创建线程

init方式创建

在需要的时候启动线程 需要手动启动

//线程执⾏行的⽅方法 -(void)downloadTask:(id)obj{    NSLog(@"当前线程:%@",[NSThread currentThread]); //模拟耗时操作    NSLog(@"%@",(NSString*)obj);}//使⽤用initWithTarget创建线程 -(void)createThreadByInit{NSLog(@"主线程:%@",[NSThread currentThread]);NSThread *thread=[[NSThread alloc]initWithTarget:self selector:@selector(downloadTask:) object:@"parameters"];//启动线程的任务 //设定线程的⼀一些属性thread.name=@"⼦子线程";//名字 thread.threadPriority=0.5;//优先级 [thread start];     NSLog(@"---------------"); }

其他用法
1.获取当前线程

[NSThread currentThread];

2.线程的调度优先级,调度优先级的取值范围是0.0 ~ 1.0,默认0.5,值越⼤大⼤大,优先级越⾼高

+ (double)threadPriority;+ (BOOL)setThreadPriority:(double)p;

3.设置线程的名字

- (void)setName:(NSString *)n;- (NSString *)name;

detach方式创建

//使⽤用detachNewThreadSelector创建线程 -(void)createThreadByDetach{[NSThread detachNewThreadSelector:@selector(downloadTask:) toTarget:self withObject:@"parameter"];}

perform方式

//使⽤用perform创建线程 -(void)createThreadByPerform{ //NSObject的实例⽅方法(self)[self performSelector:@selector(downloadTask:) withObject:@"parameter"];}

PS:
1.[NSThread currentThread]->{number = 1, name = main}:⼀一定是在主线程中被执⾏行 2.[NSThread currentThread]->{number = 2, name = (null)}:只要number不为1就是⼦子线程
3.使⽤用initWithTarget创建的线程需要使⽤用start启动。
4.使⽤用detachNewThreadSelector⾃自动创建线程并启动。

GCD

GCD的概念介绍

Crand Central Dispatch
特点:
1.不需要了解线程的内部运作原理
2.基于C语⾔言的接⼝口
3.利⽤用CPU多核的特点
4.GCD后端⾃自动管理着⼀一个线程池(重复利⽤用线程)

基本步骤:
1.创建空队列 (串⾏行队列 并⾏行队列)
2.把任务添加到队列
3.执⾏行队列中的任务(同步执⾏行 异步执⾏行)

GCD创建线程

  1. 串⾏行同步:队列中的任务顺序执⾏行;在当前线程中执⾏行
  2. 串⾏行异步:队列中的任务顺序执⾏行;在⼦子线程中执⾏行,主线程继续执⾏行不会等待⼦子线程执 ⾏行完毕
  3. 并⾏行同步(一般不⽤用):队列中的任务顺序执⾏行;在当前线程中执⾏行
  4. 并⾏行异步:队列中的任务同时执⾏行;在⼦子线程执⾏行;主线程继续执⾏行,不会等待⼦子线程执 ⾏行完毕



全局队列和主队列

全局队列:是全局的并行队列

主队列:是在主线程中的队列 (串行)

主队列不要执行同步任务 不然会导致阻塞

dispatch_once

static dispatch_once_t oneToken; dispatch_once(&oneToken,^{    });

扩展:线程安全的单例模式

//使⽤用GCD dispatch_once//适⽤用场景:多线程安全static DataCenterManager *_dataCenterByGCD = nil; + (id)sharedDataCenterByGCD {    static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{    _dataCenterByGCD = [[DataCenterManager alloc] init]; });    return _dataCenterByGCD; }

dispatch_group_async/dispatch_group_notify

//队列:全局队列//执⾏行⽅方式:dispatch_group_async()dispatch_queue_t globalQueue = dispatch_get_global_queue(0,0);//把耗时的下载的图⽚片的任务加到全局队列中,以group为单位dispatch_group_t group = dispatch_group_create();  dispatch_group_async(group, globalQueue, ^{    [NSThread sleepForTimeInterval:4];     NSLog(@"第⼀一个图⽚片下载完毕:%@", [NSThread currentThread]);    dispatch_group_async(group, globalQueue, ^{     [NSThread sleepForTimeInterval:1];    NSLog(@"第⼆二个图⽚片下载完毕:%@", [NSThread currentThread]); });    dispatch_group_async(group, globalQueue, ^{     [NSThread sleepForTimeInterval:2];    NSLog(@"第三个图⽚片下载完毕:%@", [NSThread currentThread]); });    //通知三个图⽚片下载完毕     dispatch_group_notify(group, globalQueue, ^{    NSLog(@"三个图⽚片下载完毕:%@", [NSThread currentThread]); //回到主线程    dispatch_async(dispatch_get_main_queue(), ^{        NSLog(@"回到主线程更新UI界⾯面"); });});

NSOperation

相对于GCD的优势是可以设置线程之间的依赖关系

常用概念

什么是线程,线程和进程有什么区别?

进程(process)是一块包含了某些资源的内存区域,操作系统利⽤用进程把它的⼯工作划分为
一些功能单元,一个应⽤用程序配套一个进程。 线程(thread)进程中所包含的一个或者多个执⾏行单元称为线程,线程负责执⾏行代码,一个 进程⾥里可以有多个线程。

并行队列和串行队列

串⾏行队列(Serial Dispatch Queue): 依次执⾏行队列中的线程
并⾏行队列(Concurrent Dispatch Queue): 同时执⾏行队列中的线程

同步和异步

同步(Synchronize)队列中的任务在当前线程中执⾏行(不会启动新的线程)。
异步(Asynchronize)队列中的任务在⼦子线程中执⾏行。

并行、并发

并发当有多个线程在操作时,如果系统只有⼀一个CPU,则它根本不可能真正同时进⾏行一个以上
的线程,它只能把CPU运⾏行时间划分成若干个时间段,再将时间 段分配给各个线程执⾏行,在 ⼀个时间段的线程代码运⾏行时,其它线程处于挂起状。.这种⽅方式我们称之为并发 (Concurrent)。
并行:当系统有一个以上CPU时,则线程的操作有可能⾮非并发。当一个CPU执⾏行一个线程 时,另一个CPU可以执⾏行另一个线程,两个线程互不抢占CPU资源,可以同时进⾏行,这种 ⽅方式我们称之为并⾏行(Parallel)。

临界区、临界资源

每个进程中访问临界资源的那段程序称为临界区(临界资源是⼀一次仅允许⼀一个进程使⽤用的共 享资源)。每次只准许⼀一个进程进⼊入临界区,进⼊入后不允许其他进程进⼊入。

死锁

所谓死锁: 是指两个或两个以上的进程在执⾏行过程中,由于竞争资源或者由于彼此通信⽽而
造成的一种阻塞的现象,若⽆无外⼒力作⽤用,它们都将⽆无法推进下去。此时称系统处于死锁状态
或系统产⽣生了死锁,这些永远在互相等待的进程称为死锁进程。

0 0
原创粉丝点击