美文网首页
『ios』信号量引起的卡住主线程和崩溃问题

『ios』信号量引起的卡住主线程和崩溃问题

作者: butterflyer | 来源:发表于2021-02-25 15:42 被阅读0次

    关于信号量的文章有很多,但是遇到的这两个问题,也算是采坑了吧~记录一下。


    image.png

    要做一个关于不断进入直播间的这样一个需求。
    需求是要求每个进入直播间的人都要展示进入直播间的动画。
    围绕着如何卡住这个后面的人,我想起了信号量这个东西。

    dispatch_semaphore_t _setBottom_globalInstancesLock;
    dispatch_semaphore_t _darts_globalInstancesLock;
    //执行QUEUE的Name
    char * SETBOTTOM_QUEUE_NAME = "com.SetBottom_Semaphore.queue";
    
    static void _AlertViewInitGlobal() {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _setBottom_globalInstancesLock = dispatch_semaphore_create(1);
        });
    }
    
    @implementation Aobject
    
    +(void)initialize{
        [super initialize];
        _AlertViewInitGlobal();
    }
    + (void)showWithMessageType:(ZLRTCMsgSemaphoreType)type showBlock:(void(^)(void))showBlock
    {
        if (type == ZLRTCMsgSemaphoreType_SetBottom) {
            //位于非主线程 不阻塞
            dispatch_async(dispatch_queue_create(SETBOTTOM_QUEUE_NAME, DISPATCH_QUEUE_SERIAL), ^{
                //Lock
                dispatch_semaphore_wait(_setBottom_globalInstancesLock, DISPATCH_TIME_FOREVER);
                //保证主线程UI操作
                dispatch_async(dispatch_get_main_queue(), ^{
        //            [[[UIApplication sharedApplication] keyWindow] addSubview:self];
                    showBlock();
                });
            });
        }
    }
    + (void)dismissWithMessageType:(ZLRTCMsgSemaphoreType)type dismissBlock:(void(^)(void))dismissBlock
    {
    
        if (type == ZLRTCMsgSemaphoreType_SetBottom) {
    
            dispatch_async(dispatch_queue_create(SETBOTTOM_QUEUE_NAME, DISPATCH_QUEUE_SERIAL), ^{
                //Release Lock
                dispatch_semaphore_signal(_setBottom_globalInstancesLock);
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    dismissBlock();
                });
            });
        }
    }
    

    创建一个异步串行队列,这样在一个新的队列中去处理这个卡住后面进来的人,从而实现按顺序执行的问题。想法很美好,但现实很骨感。

    第一个问题。

    刚开始把信号量作为私有变量放到消息互动区。
    这样就会出现在切换下个直播间,当前消息互动区被释放掉的时候,还处于wait状态,导致崩溃问题。原本以为在dealloc的时候,发送signal可以解决这个问题,实际上还是会崩溃。
    

    第二个问题。

    在上面我把信号量放到消息互动区的对象上,不能实现需求之后,我又想到能否放到单例中,来实现这个问题。
    刚开始确实没有问题,但当直播间人数突然激增,或者是直播半小时以上,人数不断累积到6000+的时候,就会发生卡主主线程,只能听到声音的情况。
    通过检测内存发现,在卡主之前,内存很平稳,不断wait不断signal,相互配合很好。
    但一段时间之后,卡主主线程,那么内存就在不断的增大中。
    经过压力测试,如果一秒钟发送几千条消息,那么信号量就会一直卡主,从而卡主主线程。
    这算是一个坑吧。希望看到这个文章的人可以避免这个坑。
    

    说一下最后问题的解决,我觉得这个需求,最好简单点直接拿计时器来做,不断从数组中取,时间间隔为动画的时间长度。

    相关文章

      网友评论

          本文标题:『ios』信号量引起的卡住主线程和崩溃问题

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