iOS 线程

简介: 1. pthread1). 执行不带参数的方法import - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 创建子线程,线程编号 pthr...

1. pthread

1). 执行不带参数的方法

import <pthread/pthread.h>

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 创建子线程,线程编号
    pthread_t pthread;
    // 第一个参数 线程编号的地址
    // 第二个参数 线程的属性
    // 第三个参数 线程的要执行的函数
    // 第四个参数 要执行的函数的参数
    // 返回值 int 0是成功 非0是失败
    int result = pthread_create(&pthread, NULL, demo, NULL);
    NSLog(@"touchesBegan %@", [NSThread currentThread]);
    
    if (result) {
        NSLog(@"失败");
    } else {
        NSLog(@"成功");
    }
}

// 函数必须是C语言的
void *demo(void *param) {
    NSLog(@"hello %@", [NSThread currentThread]);
    return NULL;
}

2). 执行带参数的方法

#import <pthread/pthread.h>

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 创建子线程, 线程编号
    pthread_t pthread;
    char *nameC = "mazaiting";
    int result = pthread_create(&pthread, NULL, demo, (void *)nameC);
    if (result) {
        NSLog(@"失败");
    } else {
        NSLog(@"成功");
    }
    NSString *nameNS = @"zaitingma";
    // 传参时要将OC中的对象传递给C语言的函数,要使用桥接, __bridge
    int result1 = pthread_create(&pthread, NULL, demo1, (__bridge void *)nameNS);
    if (result1) {
        NSLog(@"失败");
    } else {
        NSLog(@"成功");
    }
}
// C函数, 传递OC对象
void *demo1(void *param) {
    NSString *string = (__bridge NSString *)param;
    NSLog(@"%@", string);
    return NULL;
}

// C函数, 传递C字符串
void *demo(void *param) {
    char *string = param;
    NSLog(@"%s", string);
    return NULL;
}

2. NSThread

1). 创建线程


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self createThread];
}

- (void)createThread {
    // 方式一
    // 创建线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
    // 开启线程
    [thread start];
    
    // 方式二
    [NSThread detachNewThreadSelector:@selector(demo) toTarget:self withObject:nil];
    
    // 方式三
    [self performSelectorInBackground:@selector(demo) withObject:nil];
    
    // 方式4 带参数
    NSThread *threadParam = [[NSThread alloc] initWithTarget:self selector:@selector(demo1:) object:@"mazaiting"];
    [threadParam start];
}

- (void)demo1:(NSString *)name {
    NSLog(@"%@", name);
}

- (void)demo {
    // 打印当前线程
    NSLog(@"hello %@", [NSThread currentThread]);
}

2). 线程状态

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 新建状态
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
    // 线程名
    thread.name=@"t1";
    // 线程的优先级
    thread.threadPriority=1.0;
    // 就绪状态
    [thread start];
}

- (void)demo {
    for (int i = 0; i < 20; i++) {
        NSLog(@"%d", i);
        if (i == 5) {
            // 阻塞状态 -- 睡眠3秒
            [NSThread sleepForTimeInterval:3];
        }
        if (i == 10) {
            // 线程退出 -- 死亡状态
            [NSThread exit];
        }
        // 判断是否是主线程
        if([NSThread isMainThread]){
            continue;
        }
    }
}

3). 线程互斥锁

- (void)demo1 {
    // 互斥锁
    @synchronized(self) {
        NSLog(@"%@",self);
    }
}

4). 自旋锁

@property (nonatomic, copy) NSString *name;
// 为属性生成对应的成员变量
@synthesize name = _name;

5). 三种Block

    //2 block 为什么要用copy
    
    //第一种 block   全局block  __NSGlobalBlock__
//    void (^demo)() = ^{
//        NSLog(@"aaa");
//    };
//    NSLog(@"%@",demo);
    
    //第二种block   栈Block  __NSStackBlock__
//    int number = 5;
//    void (^demo)() = ^{
//        NSLog(@"aaa %d",number);
//    };
//    NSLog(@"%@",demo);
    
    //第三种block   堆block  __NSMallocBlock__
//    int number = 5;
//    void (^demo)() = ^{
//        NSLog(@"aaa %d",number);
//    };
//    NSLog(@"%@",[demo copy]);

6). 子线程消息循环

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 开启一个子线程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];
    [thread start];
    
    // 往子线程的消息循环中添加输入源
    [self performSelector:@selector(demo1) onThread:thread withObject:nil waitUntilDone:NO];
}

// 执行在子线程上的方法
- (void)demo {
    NSLog(@"I am running!");
    // 开启子线程的消息循环,如果开启,消息循环一直运行
    // 当子线程循环中没有添加输入事件,消息循环会立即结束
//    [[NSRunLoop currentRunLoop] run];
    
    // 2秒钟后消息循环结束
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
    NSLog(@"end");
}

// 执行在子线程的消息循环中
- (void)demo1 {
    NSLog(@"I'm running on runloop!");
}

@end

3. GCD

1). 简单使用

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 1. 创建队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    // 2. 创建任务
    dispatch_block_t task = ^ {
        NSLog(@"hello %@",[NSThread currentThread]);
    };
    // 3. 异步执行
    dispatch_async(queue, task);
    
    // 简化用法
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"mazaiting %@", [NSThread currentThread]);
        // 回到主线程
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"----%@", [NSThread mainThread]);
        });
    });
}

@end

2). 串行队列

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self sync];
    [self async];
}

// 串行队列,同步执行  不开新线程,任务是顺序执行的
- (void)sync {
    dispatch_queue_t queue = dispatch_queue_create("mazaiting", DISPATCH_QUEUE_SERIAL);
    for (int i = 0; i < 10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"%d---%@", i, [NSThread currentThread]);
        });
    }
}

// 串行队列,异步执行  开新线程(1个),任务是有序执行的
- (void)async {
    dispatch_queue_t queue = dispatch_queue_create("mazaiting", DISPATCH_QUEUE_SERIAL);
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"%d---%@", i, [NSThread currentThread]);
        });
    }
}
@end

3). 并行队列

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self sync];
    [self async];
}

// 并行队列,同步执行 --- 串行队列,同步执行,不开线程,顺序执行
- (void)sync {
    dispatch_queue_t queue = dispatch_queue_create("mazaiting", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i < 10; i++) {
        dispatch_sync(queue, ^{
            NSLog(@"%d---%@", i, [NSThread currentThread]);
        });
    }
}

// 并行队列,异步执行 --- 开多个线程,无序执行
- (void)async {
    dispatch_queue_t queue = dispatch_queue_create("mazaiting", DISPATCH_QUEUE_CONCURRENT);
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            NSLog(@"%d---%@", i, [NSThread currentThread]);
        });
    }
}

@end

4). 主队列

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
//    [self demo];
//    [self demo1];
    [self demo2];
}

// 1. 主队列,异步执行 --- 主线程,顺序执行
// 主队列特点:先执行完主线程上的代码,才会执行主队列中的任务
- (void)demo {
    for (int i = 0; i < 10; i++) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"hello %d %@", i, [NSThread currentThread]);
        });
    }
}

// 2. 主队列,同步执行 --- 主线程上执行才会死锁
// 同步执行: 会等着第一个任务执行完成后才会继续往后执行
- (void)demo1 {
    NSLog(@"开始");
    for (int i = 0; i < 10; i++) {
        // 死锁
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"hello %d %@", i, [NSThread currentThread]);
        });
    }
    NSLog(@"结束");
}

// 3. 解决死锁
- (void)demo2 {
    NSLog(@"开始");
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        for (int i = 0; i < 10; i++) {
            // 死锁
            dispatch_sync(dispatch_get_main_queue(), ^{
                NSLog(@"hello %d %@", i, [NSThread currentThread]);
            });
        }
    });
    NSLog(@"结束");
}

@end

5). 延迟执行和一次性执行

    //1 延迟执行
//    dispatch_time_t when,   延迟多长时间 精度到纳秒
//    dispatch_queue_t queue, 队列
//    dispatch_block_t block  任务
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        
//        NSLog(@"task");
//    });
    
    
    //2 一次性执行
//    for (int i = 0; i<20000; i++) {
//        static dispatch_once_t onceToken;
//        dispatch_once(&onceToken, ^{
//            NSLog(@"hello %@",[NSThread currentThread]);
//        });
//    }

6). 调度组

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

//下载三首歌曲,当歌曲都下载完毕 通知用户
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self demo2];
}

//调度组内部的原理
- (void)demo2 {
   //创建组
    dispatch_group_t group = dispatch_group_create();
    //创建队列
    dispatch_queue_t queue = dispatch_queue_create("hm", DISPATCH_QUEUE_CONCURRENT);
    
    //任务1
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
       
        NSLog(@"任务1");
        dispatch_group_leave(group);
    });
    
    //任务2
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        
        NSLog(@"任务2");
        dispatch_group_leave(group);
    });
    
    //任务3
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:2.0];
        NSLog(@"任务3");
        dispatch_group_leave(group);
    });

    
    //等待组中的任务都执行完毕,才会执行
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"over");
    });
    
    
    //等待组中的任务都执行完毕,才会继续执行后续的代码
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    
    NSLog(@"hello ");
}

//演示调度组的基本使用
- (void)demo1 {
    //创建组
    dispatch_group_t group = dispatch_group_create();
    //队列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    //下载第一首歌曲
    dispatch_group_async(group, queue, ^{
        NSLog(@"正在下载第一个歌曲");

    });
    
    //下载第二首歌曲
    dispatch_group_async(group, queue, ^{
        NSLog(@"正在下载第二个歌曲");
        [NSThread sleepForTimeInterval:2.0];
    
    });
    //下载第三首歌曲
    dispatch_group_async(group, queue, ^{
        NSLog(@"正在下载第三个歌曲");
    });
    
    //当三个异步任务都执行完成,才执行
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"over %@",[NSThread currentThread]);
    });  
}
@end

4. NSOperation

1). 创建

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 1. 调用start执行, 不会开启新线程,start方法更新操作的状态,调用main方法
    // 创建
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo) object:nil];
    NSLog(@"--%d", op.isFinished);
    // 开始执行
    [op start];
    NSLog(@"--%d", op.isFinished);
    
    // 2. 添加到队列
    // 创建操作
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demo) object:nil];
    // 添加到队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    // 将操作添加到队列
    [queue addOperation:op1];
    
}

- (void)demo {
    NSLog(@"hello %@", [NSThread currentThread]);
}

@end

2). BlockOperation

#import "ViewController.h"

@interface ViewController ()

//全局队列
@property (nonatomic, strong) NSOperationQueue *queue;
@end

@implementation ViewController
//懒加载
- (NSOperationQueue *)queue {
    if (_queue == nil) {
        _queue = [[NSOperationQueue alloc] init];
    }
    return _queue;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self demo5];
}
//演示start
- (void)demo1 {
    //创建操作
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"hello %@",[NSThread currentThread]);
    }];
    //更新op的状态,执行main方法
    [op start];  //不会开新线程
}

//把操作添加到队列
- (void)demo2 {
    //创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //创建操作
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"hello %@",[NSThread currentThread]);
    }];
    //把操作添加到队列中
    [queue addOperation:op];
}

- (void)demo3 {
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    [queue addOperationWithBlock:^{
        NSLog(@"hello %@",[NSThread currentThread]);

    }];
}

//全局队列
- (void)demo4 {
    
    
//    //并发队列,异步执行
//    for (int i = 0; i < 10; i++) {
//        [self.queue addOperationWithBlock:^{
//            NSLog(@"hello %d  %@",i,[NSThread currentThread]);
//        }];
//    }
    
}


// 操作的 completionBlock
- (void)demo5 {
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"hello %@",[NSThread currentThread]);
    }];
    
    //操作完成之后执行
    [op setCompletionBlock:^{
        NSLog(@"end %@",[NSThread currentThread]);

    }];
    
    [self.queue addOperation:op];
}

@end

3). 线程间通信

#import "ViewController.h"

@interface ViewController ()
//全局队列
@property (nonatomic, strong) NSOperationQueue *queue;
@end

@implementation ViewController

//懒加载
- (NSOperationQueue *)queue {
    if (_queue == nil) {
        _queue = [[NSOperationQueue alloc] init];
    }
    return _queue;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    
    [self.queue addOperationWithBlock:^{
      //异步下载图片
        NSLog(@"异步下载图片");
        
        //获取当前队列
//        [NSOperationQueue currentQueue]
        
        //线程间通信,回到主线程更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSLog(@"更新UI");
        }];
        
    }];
}

@end

4). 操作的依赖

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, strong) NSOperationQueue *queue;
@end

@implementation ViewController
- (NSOperationQueue *)queue {
    if (_queue == nil) {
        _queue = [NSOperationQueue new];
    }
    return _queue;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // 下载 - 解压 - 升级完成
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载");
    }];
    
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        [NSThread sleepForTimeInterval:2.0];
        NSLog(@"解压");
    }];    
    //设置优先级最高
    op2.qualityOfService = NSQualityOfServiceUserInteractive;
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"升级完成");
    }];
    //设置操作间的依赖
    [op2 addDependency:op1];
    [op3 addDependency:op2];
    
    //错误,会发生循环依赖,什么都不执行
//    [op1 addDependency:op3];
    
    
    //操作添加到队列中
    [self.queue addOperations:@[op1,op2] waitUntilFinished:NO];
    //依赖关系可以夸队列执行
    [[NSOperationQueue mainQueue] addOperation:op3];
}

@end

5). 自定义操作

  • 步骤: 继承NSOperation类,并重写main方法

CustomOperation.h

#import <Foundation/Foundation.h>

@interface CustomOperation : NSOperation

@end

CustomOperation.m

#import "CustomOperation.h"

@implementation CustomOperation

- (void)main {
    NSLog(@"mazaiting");
}
@end

ViewController.m

#import "ViewController.h"
#import "CustomOperation.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    CustomOperation *co = [[CustomOperation alloc] init];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:co];
}
@end
目录
相关文章
|
3月前
|
iOS开发
多线程和异步编程:解释 iOS 中的同步和异步任务的概念。
多线程和异步编程:解释 iOS 中的同步和异步任务的概念。
37 1
|
7月前
|
iOS开发
iOS多线程之NSOperationQueue-依赖、并发数、优先级、自定义Operation等最全的使用总结
iOS多线程之NSOperationQueue-依赖、并发数、优先级、自定义Operation等最全的使用总结
217 0
|
7月前
|
安全 调度 C语言
iOS多线程之GCD-同步、异步、并发、串行、线程组、栅栏函数、信号量等全网最全的总结
iOS多线程之GCD-同步、异步、并发、串行、线程组、栅栏函数、信号量等全网最全的总结
488 1
|
11月前
|
安全 算法 编译器
iOS线程安全——锁(二)
iOS线程安全——锁(二)
119 0
|
11月前
|
存储 安全 API
iOS线程安全——锁(一)
iOS线程安全——锁(一)
210 0
|
iOS开发
iOS多线程的初步研究-- dispatch同步
GCD提供两种方式支持dispatch队列同步,即dispatch组和信号量。
147 0
|
API iOS开发
iOS多个线程发起相同请求,避免重复
有时候在调用多个模块时,会对同一个API进行多次请求,但因为内容都是一样的,所以最好就是加上锁,防止重复请求造成网络资源浪费
152 0
|
敏捷开发 安全 Unix
iOS开发 - 在实战中挖掘之线程间的通信方式
iOS开发 - 在实战中挖掘之线程间的通信方式
154 0
|
程序员 C语言 iOS开发
iOS的三种多线程技术
iOS的三种多线程技术
182 0
|
调度 C++ iOS开发
IOS_多线程
IOS_多线程
88 0