美文网首页
iOS 多线程

iOS 多线程

作者: 孤独的剑客 | 来源:发表于2018-07-11 17:32 被阅读9次
    1.线程和进程的区别?

    总的来说一个进程有多个线程
    进程有独立的地址空间,一个进程崩溃后,在保护模式的影响下不会对其他进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等同于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

    2.队列、同步异步

    1.有多少种队列?

    • 串行队列
    dispatch_queue_create("com.starming.serialqueue", DISPATCH_QUEUE_SERIAL)
    

    一个任务执行完成,在执行下一个任务

    • 并行队列
    dispatch_queue_create("com.starming.concurrentqueue", DISPATCH_QUEUE_CONCURRENT)
    

    并发执行,而且无法确定任务的执行顺序

    • 全局队列
    dispatch_get_global_queue
    

    全局队列也是并行队列

    • 主队列
    dispatch_get_main_queue
    

    每一个应用程序只有一个主线程即只有一个主队列
    2.同步、异步的区别
    同步、异步:是否具备开启新线程的能力
    同步:dispatch_sync
    异步:dispatch_async

    3.几种多线程的表示方法?
    • NSThread
      需要启动线程,线程执行的优先级可以设置,最高为1
    • NSOperation
    • GCD
      1.dispatch_after 延后执行
      dispatch_after只是延时提交block,不是延时立刻执行。
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t) (delayInSeconds * NSEC_PER_SEC));
         dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
              [self bar];
         });
    
    

    2.dispatch_once 只执行一次
    dispatch_once_t要是全局或static变量,保证dispatch_once_t只有一份实例

    + (UIColor *)boringColor;
    {
         static UIColor *color;
         //只运行一次
         static dispatch_once_t onceToken;
         dispatch_once(&onceToken, ^{
              color = [UIColor colorWithRed:0.380f green:0.376f blue:0.376f alpha:1.000f];
         });
         return color;
    }
    

    3.Dispatch_groups
    dispatch groups是专门用来监视多个异步任务。dispatch_group_t实例用来追踪不同队列中的不同任务。
    当group里所有事件都完成GCD API有两种方式发送通知,第一种是dispatch_group_wait,会阻塞当前进程,等所有任务都完成或等待超时。第二种方法是使用dispatch_group_notify,异步执行闭包,不会阻塞。

    dispatch_queue_t concurrentQueue = dispatch_queue_create("com.starming.gcddemo.concurrentqueue",DISPATCH_QUEUE_CONCURRENT);
        dispatch_group_t group = dispatch_group_create();
        //在group中添加队列的block
        dispatch_group_async(group, concurrentQueue, ^{
            [NSThread sleepForTimeInterval:2.f];
            NSLog(@"1");
        });
        dispatch_group_async(group, concurrentQueue, ^{
            NSLog(@"2");
        });
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        NSLog(@"go on");
    
    4.线程锁

    在上锁和开锁之间的这个段代码只能单个线程进行访问,只有当一个线程运行到开锁之后,另一个线程才可以进入。这个操作也可以称为线程同步。
    这一块常用的锁有:NSLock、synchornized、NSCondition
    FMDB如何使用dispatch_queue_set_specific和dispatch_get_specific来防止死锁

    static const void * const kDispatchQueueSpecificKey = &kDispatchQueueSpecificKey;
    //创建串行队列,所有数据库的操作都在这个队列里
    _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
    //标记队列
    dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL);
    
    //检查是否是同一个队列来避免死锁的方法
    - (void)inDatabase:(void (^)(FMDatabase *db))block {
        FMDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey);
        assert(currentSyncQueue != self && "inDatabase: was called reentrantly on the same queue, which would lead to a deadlock");
    }
    

    相关文章

      网友评论

          本文标题:iOS 多线程

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