• 多线程之-NSThread


    多线程之-NSThread

    介绍NSThread之前先介绍一下pthread,仅供了解,一般在开发中用不到的

    pthread(了解)

    • 类型:
      • C语言中类型的结尾通常 _t/Ref,而且不需要使用 *
    /*
    参数说明:
         1. pthread_t *restrict 线程代号的地址
         2. const pthread_attr_t *restrict 线程的属性
         3. 调用函数的指针
            - void *(*)(void *)
            - 返回值 (函数指针)(参数)
            - void * 和 OC 中的 id 是等价的
         4. void *restrict 传递给该函数的参数
    返回值:
         如果是0,表示正确
         如果是非0,表示错误码
    */
    NSString *str = @"lnj";
        pthread_t thid;
        int res = pthread_create(&thid, NULL, &demo, (__bridge void *)(str));
        if (res == 0) {
            NSLog(@"OK");
        } else {
            NSLog(@"error %d", res);
        }
    

    NSThread

    • 一个NSThread对象就代表一条线程

    创建线程的几种方式:

    1. alloc/init
        // 1.创建线程
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(demo:) object:@"lnj"];
        // 设置线程名称
        [thread setName:@"xmg"];
        // 设置线程的优先级
        // 优先级仅仅说明被CPU调用的可能性更大
        [thread setThreadPriority:1.0];
        // 2.启动线程
        [thread start];
    
    • 主线程相关用法
    + (NSThread *)mainThread; // 获得主线程
    - (BOOL)isMainThread; // 是否为主线程
    + (BOOL)isMainThread; // 是否为主线程
    
    获得当前线程
    NSThread *current = [NSThread currentThread];
    
    线程的名字
    - (void)setName:(NSString *)n;
    - (NSString *)name;
    
    1. detach/performSelector
      • 优点:简单快捷
      • 缺点:无法对线程进行更详细的设置
    // 1.创建线程后自动启动线程
    [NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"lnj"];
    
    // 1.创建线程
    // 注意: Swift中不能使用, 苹果认为这个方法不安全
    
    // 隐式创建并启动线程
    [self performSelectorInBackground:@selector(demo:) withObject:@"lnj"];
    
    • 线程状态

    控制线程状态

    启动线程
    - (void)start; 
    // 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态
    
    阻塞(暂停)线程
    + (void)sleepUntilDate:(NSDate *)date;
    + (void)sleepForTimeInterval:(NSTimeInterval)ti;
    // 进入阻塞状态
    //例:
        // 睡眠5秒钟
        [NSThread sleepForTimeInterval:5];   
        // 从当前时间睡3秒
        [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
    
    
    
    强制停止线程
    + (void)exit;
    // 进入死亡状态
    

    注意:一旦线程停止(死亡)了,就不能再次开启任务


    互斥锁

    • 多线程的安全隐患

      • 被锁定的代码同一时刻只能有一个线程执行
    • 互斥锁使用格式:

    @synchronized(锁对象) 
    { 
        // 需要锁定的代码  
    }
    // 解锁
    
    • 互斥锁的优缺点

      • 优点:能有效防止因多线程抢夺资源造成的数据安全问题
      • 缺点:需要消耗大量的CPU资源
    • 互斥锁注意点

      • 锁定1份代码只用1把锁,用多把锁是无效的
      • 锁定范围越大, 性能越差

    • 线程间的通信

      •   在子线程中加载数据,回到主线程中刷新UI
    • 原子和非原子属性

      • atomic:线程安全,需要消耗大量的资源
      • nonatomic:非线程安全,适合内存小的移动设备
    • 自旋锁 & 互斥锁

      • 共同点
        • 都能够保证同一时间,只有一条线程执行锁定范围的代码
      • 不同点
        • 互斥锁:如果发现有其他线程正在执行锁定的代码,线程会进入"休眠"状态,等待其他线程执行完毕,打开锁之后,线程会被"唤醒"
        • 自旋锁:如果发现有其他线程正在执行锁定的代码,线程会"一直等待"锁定代码执行完成! 自旋锁更适合执行非常短的代码
  • 相关阅读:
    【C#新特性】不用out ref同时返回多个值-元组Tuple
    【数据处理】SQL Server高效大数据量存储方案SqlBulkCopy
    【WinForm程序】注册热键快捷键切换
    【面试题】新东方.NET工程师面试题总结
    【EF框架】另一个 SqlParameterCollection 中已包含 SqlParameter。
    【EF框架】使用params参数传值防止SQL注入报错处理
    【EF框架】EF DBFirst 快速生成数据库实体类 Database1.tt
    【接口安全】接口合法性验证加密验签SIGN 签名规则
    【激活码汇总】各种软件激活码整理 亲测可用
    requests实现接口自动化(一)
  • 原文地址:https://www.cnblogs.com/wxdonly/p/5097271.html
Copyright © 2020-2023  润新知