iOS 멀티스레드: GCD 큐 유형을 정확히 인식

5021 단어 iOS
면접을 보거나 OS프로그래밍 경험이 있는 사람들과 GCD의 대기열 유형에 대한 질문을 나눈다.
많은 사람들이 사용자 정의queue가 직렬 대기열이라고 말한다.
이런 견해는 어느 정도는 옳지 않으니, 다음에 구체적으로 다시 이야기하자.
오늘 여러분과 GCD의 대기열 유형 문제를 이야기합시다.
------------------------------------------------------------------------------------------------
현재 GCD에는 세 가지 대기열 유형이 있습니다.
*main queue: 홈팀열. 
* 글로벌 queue: 글로벌 대기열.
* custom queue: 사용자 정의 대기열.
------------------------------------------------------------------------------------------------
다음은 구체적으로 이야기합시다!
1. main queue
* 구입 방법
dispatch_get_main_queue()

* 자세히 설명
일반적으로 main queue를 사용하는데, 모두 이 라인에서 UI를 조작하는 것과 관련이 있다.
즉,mainqueue에서 실행되는 임무는 주 라인에서 실행됩니다.
메인 라인은 하나뿐이고mainqueue는 메인 라인과 관련이 있기 때문에mainqueue는 직렬 대기열입니다.global queue
* 구입 방법
dispatch_get_global_queue(long identifier, unsigned long flags);

첫 번째 파라미터는 라인의 우선순위입니다.
두 번째 매개변수는 예약된 매개변수입니다.일반적으로 0으로 설정됩니다.
공식 주석 참조 가능
/*!
 * @function dispatch_get_global_queue
 *
 * @abstract
 * Returns a well-known global concurrent queue of a given quality of service
 * class.
 *
 * @discussion
 * The well-known global concurrent queues may not be modified. Calls to
 * dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc., will
 * have no effect when used with queues returned by this function.
 *
 * @param identifier
 * A quality of service class defined in qos_class_t or a priority defined in
 * dispatch_queue_priority_t.
 *
 * It is recommended to use quality of service class values to identify the
 * well-known global concurrent queues:
 *  - QOS_CLASS_USER_INTERACTIVE
 *  - QOS_CLASS_USER_INITIATED
 *  - QOS_CLASS_DEFAULT
 *  - QOS_CLASS_UTILITY
 *  - QOS_CLASS_BACKGROUND
 *
 * The global concurrent queues may still be identified by their priority,
 * which map to the following QOS classes:
 *  - DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED
 *  - DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT
 *  - DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY
 *  - DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND
 *
 * @param flags
 * Reserved for future use. Passing any value other than zero may result in
 * a NULL return value.
 *
 * @result
 * Returns the requested global queue or NULL if the requested global queue
 * does not exist.
 */

* 자세히 설명
글로벌 queue는 병렬 대기열입니다.우선 순위를 설정할 수 있습니다.
3. Custom queue
* 구입 방법
dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

* 자세히 설명
이 대기열들은 직렬일 수도 있고, 병렬일 수도 있다.기본값은 Serial입니다.직렬 대기열은 임무가 직렬이고 집행 순서를 보장할 수 있다.유사한 자물쇠 메커니즘.
* 예
(1). 기본값은 직렬 큐입니다.
    //      (NULL,        )
    dispatch_queue_t queue = dispatch_queue_create("gcd.mark", NULL);
    
    NSLog(@"create custom queue completed.");
    
    dispatch_async(queue, ^{
        //     
        [NSThread sleepForTimeInterval:2];
        NSLog(@"Run First Task");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"Run Sencond Task");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"Run Third Task");
    });

실행 결과
//     
2015-10-31 23:33:14.267 dsds[87226:1308349] create custom queue completed.
2015-10-31 23:33:16.269 dsds[87226:1308582] Run First Task
2015-10-31 23:33:16.270 dsds[87226:1308582] Run Sencond Task
2015-10-31 23:33:16.270 dsds[87226:1308582] Run Third Task

상술한 방식으로 만든queue는 직렬 대기열임을 알 수 있습니다.그래서 처음에 다른 사람이 사용자 정의queue가 직렬이라고 말하는 것이 반드시 틀린 것은 아니다.
이어서 두 번째 예를 보아라.
(2). Serial로 지정
//        
    dispatch_queue_t queue = dispatch_queue_create("gcd.mark", DISPATCH_QUEUE_SERIAL);
    
    NSLog(@"create custom queue completed.");
    
    dispatch_async(queue, ^{
        //     
        [NSThread sleepForTimeInterval:2];
        NSLog(@"Run First Task");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"Run Sencond Task");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"Run Third Task");
    });

실행 결과는 예(1)와 일치한다.
(3). 병렬로 지정
    //        
    dispatch_queue_t queue = dispatch_queue_create("gcd.mark", DISPATCH_QUEUE_CONCURRENT);
    
    NSLog(@"create custom queue completed.");
    
    dispatch_async(queue, ^{
        //     
        [NSThread sleepForTimeInterval:2];
        NSLog(@"Run First Task");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"Run Sencond Task");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"Run Third Task");
    });

실행 결과
2015-10-31 23:37:06.052 dsds[87270:1310892] create custom queue completed.
2015-10-31 23:37:06.052 dsds[87270:1310988] Run Sencond Task
2015-10-31 23:37:06.052 dsds[87270:1311060] Run Third Task
2015-10-31 23:37:08.057 dsds[87270:1311055] Run First Task

순서대로 집행된 것이 아니라는 것을 알 수 있다.

좋은 웹페이지 즐겨찾기