多线程

线程

  • 一个进程要想执行任务, 就必须开启线程.
  • 一个线程同一时间只能执行一个任务(线程内部是串行的).

多线程

  • CPU 通过操控多个线程切换, 并行执行任务!
  • 提高效率;
  • 线程开销, 耗性能, 发热耗电;

主线程

  • UI线程, 刷新UI 界面, 处理点击事件;
  • 防止线程阻塞.
First Header Second Header
pthread C
NSThread OC
GCD C
NSOperation C
  • 线程的状态
    runnable, running, blocked(sleep), dead

    [NSThread exit];
    [NSThread sleepForTimeInterval:2.f];
    
state.png
  • Pthread

     /**
         POSIX 多线程开发框架
    
     pthread_t  _Nullable *restrict _Nonnull: 指向线程代号的指针
     const pthread_attr_t *restrict _Nullable: 线程的属性
     void * _Nullable (* _Nonnull)(void * _Nullable): 指向函数的指针
     void *restrict _Nullable: 传递给该函数的参数
    
     返回值:
    - 如果是0, 标识正确
    - 非0, 错误
     void *  (*)    (void *)
     返回值   函数指针  id
    
     ARC 中用到 C 语言中数据类型, 需要进行桥接转换;
     __bridge (需要设置 free )
     MRC 不需要
    */
    pthread_t threadId;
    
    NSString *str = @"hello world";
    int result = pthread_create(&threadId, NULL, &demo, (__bridge void *)(str));
    
    if (result == 0) {
        NSLog(@"success");
    } else {
        NSLog(@"error");
    }
    
  • NSThread

    - (void)nsthreadDemo1 {
      NSLog(@"_______1________");
      // 1. 创建线程(子线程)
      NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(thread1Method:)         object:@"obj"];
      // 开启线程
      [thread1 start];
    
      // 2. 不用手动开启
      [NSThread detachNewThreadWithBlock:^{
          [self thread1Method:@"block"];
          [self performSelector:@selector(thread1Method:) withObject:@"perform"];
      }];
    
      [NSThread detachNewThreadSelector:@selector(thread1Method:) toTarget:self withObject:@"target"];
    
      // 3. map
      // 默认当前线程
    //    [self performSelector:@selector(thread1Method:) withObject:@"perform"];
      // 子线程
      [self performSelectorInBackground:@selector(thread1Method:) withObject:@"background"];
      NSLog(@"_______2________");
    }
    
  • 互斥锁(synchronized)

    • 保证代码在同一时间内, 只能执行一行代码!
    • 使用范围尽量小;
    • 参数应为线程全局变量(保证锁唯一性)! (若为线程私有变量, 加锁无效)
    自旋锁 互斥锁
    保证线程安全 保证线程安全
    耗性能 耗性能
    被锁在外面的线程, 用死循环的方式等待解锁 被锁在外面的线程, 进入休眠状态, 待锁打开后被唤醒
    read 不会加锁, write 回加锁 read, write 都会加锁
     @synchronized(self){
                if (self.ticket > 0) {
                    self.ticket--;
                    NSLog(@"left = %d --- %@", self.ticket, [NSThread currentThread]);
                }else{
              
                    NSLog(@"sale out -- %@", [NSThread currentThread]);
                    break;
                }
        }
    

atomic: 原子性
修饰的属性, 默认有一个自旋锁(单线程写, 多线程读);
保证多个线程访问这个对象的时候, 同一时间只有一个线程能够执行!
先把文件保存在一个临时文件中, 等全部写入之后, 再改名字!

[@"" writeToFile:<#(nonnull NSString *)#> atomically:<#(BOOL)#> encoding:<#(NSStringEncoding)#> error:<#(NSError * _Nullable __autoreleasing * _Nullable)#>];

nonatomic: 非原子性

线程安全: 在多个线程同时进行读写操作时, 任然能保证数据安全. 所以约定在主线程进行UI 刷新, 是为了保证线程安全

你可能感兴趣的:(多线程)