Abandoned Dispatch_get_current_queue.

Source: Internet
Author: User
Tags gcd

Want to talk about abandoned Dispatch_get_current_queue, have to mention a concept: can be reentrant.

What is reentrant, from Wikipedia: If a program or subroutine can be "securely executed in parallel (Parallel computing)", it is said to be reentrant (reentrant or re-entrant).

That is, when the subroutine is running, it can be entered and executed again (in parallel execution, individual execution results are consistent with design-time expectations).

If a function is reentrant, the function:

Cannot contain static (global), very measured data

Cannot return the address of the static (global) extraordinary amount data

Can only handle data supplied by the caller

Cannot rely on a single instance schema resource lock

A function that cannot be called (call) cannot be reentrant (calls) to a function that satisfies the aforementioned conditions)

Sometimes we want to know who the queue is currently executing, such as UI operations that need to be executed in the main queue. If you know who the current queue is, it is convenient to specify a piece of code to execute in a particular queue. Dispatch_get_current_queue () is just the right time to help. Thus, doing something in the specified queue can be implemented very clearly:

void func (dispatch_queue_t queue, dispatch_block_t block)    
{    
    if (dispatch_get_current_queue () = = queue) {    
        Block ();    
    } else{    
        Dispatch_sync (queue, block);    
    }    

Then subconsciously, think of this function as reentrant.

However, when the target queue happens to be the current queue, synchronization blocking can cause deadlocks.

-(void) Deadlockfunc    
{    
    dispatch_queue_t QueueA = dispatch_queue_create ("Com.yiyaaixuexi.queueA", NULL);    
    dispatch_queue_t Queueb = dispatch_queue_create ("Com.yiyaaixuexi.queueB", NULL);    
    Dispatch_sync (QueueA, ^{    
        dispatch_sync (Queueb, ^{dispatch_block_t block    
            = ^{//do something    
            };    
            Func (QueueA, Block);});}    

The problem is that the GCD queue itself is not reentrant, and the hierarchical relationship of the serial synchronization queues is the root cause of the problem.

More Wonderful content: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/project/

To prevent similar misuse, Apple abandoned the Dispatch_get_current_queue () method in IOS6. The powerful dispatch_get_current_queue () can only be used as a debugging tool.

So how should the GCD method be guaranteed to be reentrant?

Dispatch_queue_set_specific Tag Queue

Recursive locks

A sample code fragment of two methods is given, respectively:

1) dispatch_queue_set_specific

dispatch_queue_t QueueA = dispatch_queue_create ("Com.yiyaaixuexi.queueA", NULL);    
   dispatch_queue_t Queueb = dispatch_queue_create ("Com.yiyaaixuexi.queueB", NULL);    
   Dispatch_set_target_queue (Queueb, QueueA);    
          
   static int specifickey;    
   Cfstringref Specificvalue = cfstr ("QueueA");    
   Dispatch_queue_set_specific (QueueA,    
                               &specifickey,    
                               (void*) Specificvalue,    
                               (dispatch_function_t) Cfrelease);    
          
   Dispatch_sync (Queueb, ^{    
       dispatch_block_t block = ^{//do something    
       };    
       Cfstringref Retrievedvalue = dispatch_get_specific (&specifickey);    
       if (retrievedvalue) {block    
           ();    
       } else {    
           Dispatch_sync (QueueA, Block);}}    
   );

2) Recursive lock

void Dispatch_reentrant (void (^block) ())    
{    
    static nsrecursivelock *lock = nil;    
    Static dispatch_once_t Oncetoken;    
    Dispatch_once (&oncetoken, ^{    
        lock = [[Nsrecursivelock alloc]init];    
    });    
    [Lock lock];    
    Block ();    
    [Lock unlock];    
}    
        
    dispatch_queue_t QueueA = dispatch_queue_create ("Com.yiyaaixuexi.queueA", NULL);    
    dispatch_block_t block = ^{    
         //do something    
    };    
    Dispatch_sync (QueueA, ^{    
        dispatch_reentrant (block);    
    });

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.