GCD의 사라진 자물쇠 체험

1895 단어 GC
1. 먼저 코드 몇 마디를 본다
dispatch_queue_t serialqueue=dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);//      

    dispatch_sync(serialqueue, ^{

        NSLog(@"1");

    });

    dispatch_sync(dispatch_get_main_queue(), ^{

        NSLog(@"2");

    });


2.앞의 블로그에 GCD의 사라진 자물쇠를 썼다http://www.cnblogs.com/cuiyw/p/4369041.html이렇게 적혀있다: 잠금 방지 비적: 직렬 대기열에 디스패치 넣지 마세요sync、dispatch_apply, 요 며칠 동안 이 말을 생각하고 있었어요. 오늘 사용자가 정의한 스레드 대기열을 볼 때 직렬 스레드 대기열을 봤어요. 그래서 말이 정확한지 검증하고 싶었어요. 위처럼 쓰면 둘 다 잠길 줄 알았어요. 실행해 보니 생각보다 안 그래요.첫 번째로 출력할 수 있다는 사실에 나는 깜짝 놀랐다. 이 말이 옳지 않은 것이 틀린 줄 알았다.동기화 비동기를 보고 코드를 두드려 보니 자기가 잘못 이해한 것 같았다.
3.dispatch_sync、dispatch_apply, 이것들은 모두 동기화를 나타낸다.동기화는 현재 스레드를 막습니다. 매개 변수의 Block 문장을 매개 변수의 스레드 대기열에 추가하여 실행합니다. 실행이 끝난 후에 막힌 곳으로 돌아가서 계속 실행합니다.
예를 들어 위의 두 동기화:
첫 번째: 현재 실행 중인 것은 주 루틴 대기열,mian queue,dispatchsync 시, 주 루틴이 끊기고, 블록을 사용자 정의 직렬 루틴 대기열에 추가하기 시작하며, 실행이 끝난 후에 현재 주 루틴 대기열main queue로 돌아갑니다.그래서 사라진 자물쇠가 생기지 않는다.
두 번째: 현재 메인 라인이 두 번째 동기화에 실행될 때 막혀서 블록을 메인 라인 대기열에 추가하기 시작합니다. 이때 메인 라인 대기열은 블록이 실행되기를 기다리고 블록 이쪽은 메인 라인 대기열이 실행되기를 기다리면 사라진 자물쇠가 생깁니다.
4. 다음 코드를 살펴보십시오.
 dispatch_sync(queue,^{

         dispatch_async(dispatch_get_main_queue(), ^{

             NSLog(@"1");

         });

    });

    dispatch_sync(queue,^{

        dispatch_sync(dispatch_get_main_queue(), ^{

            NSLog(@"2");

        });

    });


위의 두 부분의 코드는 첫 번째는 잠기지 않고 두 번째는 잠기지 않는다.
개인의 분석과 이해가 반드시 정확한 것은 아니다.
첫 번째: 주 루틴은 직렬 루틴 대기열입니다.sync를 실행할 때 주 루틴 대기열을 막습니다. 전역 루틴 대기열에 Block을 추가하고 전역 루틴 대기열을 열면 가장 안쪽에 있는 Block을 주 루틴 직렬 대기열에 추가합니다. 이 때 원래 막혔던 위치로 되돌아갈 수 있습니다.
두 번째: 주 루틴이sync에 실행될 때 주 루틴 대기열을 막고 전역 루틴 대기열에 Block을 추가합니다. 전역 루틴 대기열을 동기화하여 가장 안쪽에 있는 Block을 주 루틴 대기열에 추가합니다. 이때 주 루틴 대기열은 Block의 귀환을 기다리고 Block은 주 루틴 대기열이 실행되고 주 루틴 대기열에 추가되면 사라집니다.

좋은 웹페이지 즐겨찾기