美文网首页
多线程01 pthread NSThread 多线程的资源共享问

多线程01 pthread NSThread 多线程的资源共享问

作者: xwf_code | 来源:发表于2016-10-17 20:40 被阅读0次

    凡是跟UI相关的都是在主线程执行的

    UIKit类库的线程都是不安全的 所以我们需要在主线程上更新UI 因此主线程又叫UI线程

    多线程的核心思想 : 就是把耗时操作放在后台执行,避免耗时操作卡死UI

    currentThread : 查看当前线程

    NSLog(@"%@",[NSThread currentThread]);

    同步和异步

    同步和异步是任务 / 代码 执行的两种方式

    同步--->多个任务按顺序依次执行,就是同步执行

    异步--->多个任务同时执行,就是异步执行

    pthread

    参数1 : 子线程的ID / 标识

    在C语言中,一般带`_t` / `_ref`标识数据类型

    参数2 : 子线程的属性,一般传NULL

    NULL : 表示空地址,一般在C语言使用;

    nil : 表示空对象,一般在OC使用;

    其实,NULLh和nil本质上没有半点儿区别

    参数3 : 子线程需要执行的函数

    void *(*)(void *) : 表示指向函数的指针,即函数名;函数名就是表示函数地址;

    数组地址就是数组名或者数组第0个角标元素的地址

    void * 表示可以指向任何地址的指针,代表任意数据类型;类似于OC的id;

    返回值    函数名    函数参数

    void *    (*)    (void *)

    参数4 : 传入到子线程需要执行的函数的参数

    返回值 : int;在很多C语言框架中,并不是遵守非零既真;因为成功的结果只有一个,0是唯一的;失败的原因有很多;

    线程调试 : 查看方法执行的线程是否是主线程或者子线程

    {number = 1, name = main} : 表示主线程

    {number = 3, name = (null)} : 只要number != 1 就表示子线程

    提示 : 千万不要纠结number到底等于几,系统分配的

    // 参数1

    pthread_t ID;

    // 创建了一个子线程,执行demo函数

    int result = pthread_create(&ID, NULL, demo, NULL);

    // 判断创建子线程是否成功

    if (result == 0) {

    NSLog(@"创建子线程成功");

    } else {

    NSLog(@"创建子线程失败");

    }

    子线程执行的函数

    */

    void *demo(void *param)

    {

    NSString *str = (__bridge NSString *)(param);

    // currentThread : 查看当前线程

    NSLog(@"demo %@ - %@",[NSThread currentThread],str);

    return NULL;

    }

    NSThread创建线程三种方式

    [self performSelectorInBackground:@selector(demo:) withObject:@"perform"];

    以上参数介绍:

    1.NSObject分类方法创建子线程

    2.不可以拿到线程对象

    3.不需要手动启动线程

    [NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"detach"];

    以上参数介绍:

    1.类方法创建子线程

    2.不可以拿到线程对象

    3.不需要手动启动线程

    // 创建线程对象

    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo:) object:@"alloc"];

    // 启动线程

    [thread start];

    以上参数介绍:

    1.构造方法创建子线程

    2.可以拿到线程对象

    3.需要手动启动线程

    通知主线程刷新UI

    // waitUntilDone : 是否等待updateUI执行完,再执行后面的代码,一般传入NO

    [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO];

    关于以上使用调用方法中-target和selector关系

    @selector中需要传入一个方法

    而target中需要传入对象告诉系统 这个方法是哪个对象的

    线程的声明周期

    提示 : 程序员只能做新建和就绪,其他的都由系统来处理

    // 创建线程对象 : 新建状态

    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];

    // 启动线程 : 就绪状态(把线程对象添加到可调度线程池,等待被CPU调度执行)

    [thread start];

    // sleepForTimeInterval : 使当前线程休眠到指定时长

    [NSThread sleepForTimeInterval:1.0];

    // sleepUntilDate : 使当前线程休眠到指定日期

    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.0]];

    // 使当前线程强制死亡

    [NSThread exit];

    线程的属性

    //新建状态

    NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(demo) object:nil];

    // 设置线程对象的name属性 : 标识一个唯一的线程对象,方便跟踪

    thread1.name = @"t1";

    thread1.threadPriority = 1.0;

    // 设置线程对象的优先级 : 浮点数;范围是0.0~1.0;最高是1.0;默认是0.5

    // 线程优先级不能决定线程执行的先后顺序,只能决定某个线程有更多的机会被CPU先调度执行完,概率事件

    // 注意 : 实际开发中,千万不要设置优先级或者服务器质量,会出现意想不到的问题;使用默认的,让系统自己来处理

    // threadPriority : 在目前即将被废弃,使用qualityOfService来替代;

    thread1.qualityOfService = NSQualityOfServiceUserInteractive;

    // stackSize : 线程占用内存空间大小

    NSLog(@"子 %tu",[NSThread currentThread].stackSize / 1024);

    多线程的资源共享问题

    // 互斥锁 / 同步锁 : 使用了线程同步技术

    // 特点 : 可以保证被锁定的代码,同一时间只有一个线程可以访问

    // self : 表示互斥锁的参数;互斥锁的参数,又叫做锁对象;

    // 锁对象 : 任何继承自NSObject的对象,都可以作为互斥锁的参数;内部有把锁,默认是开启的

    // 锁对象必须是全局的对象;self是最方便获取的全局的锁对象

    // 局部锁对象是锁不住的,因为每次线程进来之前会新建一把锁

    // 提示 : 加锁的事情,不是再客户端操作的;是服务器加锁的,多线程资源共享绝大多数是在服务器发生;

    // 提示 : 加锁是牺牲了性能,保证安全.客户端的性能不能轻易牺牲

    @synchronized (self)

    {

          //需要被锁定的代码

    }

    参数必须传全局对象 多数传self 

    原子属性

    使用nonatomic修饰的属性为非原子属性

    使用atomic修饰的属性为原子属性

    原子属性 : 单写多读

    单写多读 : 同一时间只有一个线程可以访问setter方法;但是可以有多个线程访问getter方法

    注意 : 原子属性的setter方法是线程安全的,getter方法是线程非安全的

    setter方法内部有把自旋锁

    自旋锁 :

     看不见的,由系统封装的

    可以保证被锁定的代码,同一时间只能有一个线程可以访问

    一旦外面的线程,发现代码被自旋锁锁定,外面的线程会以死循环的方式等待开锁

    互斥锁 :

    可以保证被锁定的代码,同一时间只能有一个线程可以访问

    一旦外面的线程,发现代码被互斥锁锁定,外面的线程会进入就绪状态,等待开锁

    相关文章

      网友评论

          本文标题:多线程01 pthread NSThread 多线程的资源共享问

          本文链接:https://www.haomeiwen.com/subject/serzyttx.html