iOS uses semaphores to handle multiple image uploads

A semaphore is a resource counter, and there are two operations on the semaphore to achieve mutual exclusion, namely P and V operations. The general situation is to perform critical access or mutually exclusive access as follows: Set the semaphore value to 1, when a process 1 is running, use the resource and perform the P operation, that is, the semaphore value is reduced by 1, that is, the number of resources is reduced by 1 . This is the semaphore value of 0. It is stipulated in the system that when the semaphore value is 0, it must wait until the semaphore value is not zero before continuing to operate. At this time, if process 2 wants to run, it must also perform the P operation, but at this time the semaphore is 0, so it cannot be decremented by 1, that is, the P operation cannot be performed, and it is blocked. This gives process 1 exclusive access. When process 1 finishes running, release resources and perform V operation. The number of resources is re-added by 1, which means that the value of the semaphore becomes 1. At this time, process 2 finds that the number of resources is not 0, the semaphore can perform the P operation, and immediately executes the P operation. The semaphore value becomes 0 again. The number of times process 2 has resources and accesses resources exclusively. This is the principle of semaphore to control mutual exclusion.

How GCD uses semaphores

How to synchronize threads when we use GCD, there are only three I can think of at the moment

  • 1.dispatch_group
  • 2.dispatch_barrier
  • 3.dispatch_semaphore

1 and 2 are simpler and more commonly used. Not introduced here. If you are not sure, you can refer to concurrency. It is actually very simple
. Here I mainly talk about dispatch_semaphore

There are three functions in GCD that are semaphore operations,
namely:  

  1. dispatch_semaphore_create creates a semaphore 
  2. dispatch_semaphore_signal sends a signal 
  3. dispatch_semaphore_wait waits for a signal

Briefly introduce these three functions. The first function has an integer parameter, which we can understand as the total amount of signals. dispatch_semaphore_signal is to send a signal, which will naturally increase the total amount of signals by 1. dispatch_semaphore_wait waits for the signal. When the amount is less than 0, it will wait all the time, otherwise it can be executed normally and let the total amount of signals -1. According to this principle, we can quickly create a concurrency control to synchronize tasks and limited resource access control.

see code

// 创建队列组
    dispatch_group_t group = dispatch_group_create();   
// 创建信号量,并且设置值为10
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);   
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);   
    for (int i = 0; i < 100; i++)   
    {   // 由于是异步执行的,所以每次循环Block里面的dispatch_semaphore_signal根本还没有执行就会执行dispatch_semaphore_wait,从而semaphore-1.当循环10此后,semaphore等于0,则会阻塞线程,直到执行了Block的dispatch_semaphore_signal 才会继续执行
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);   
        dispatch_group_async(group, queue, ^{   
            NSLog(@"%i",i);   
            sleep(2);   
// 每次发送信号则semaphore会+1,
            dispatch_semaphore_signal(semaphore);   
        });   
    }

The above comments have explained how to control thread synchronization by controlling semaphores. The key is this sentence:

// Because it is executed asynchronously, dispatch_semaphore_wait will be executed every time the dispatch_semaphore_signal in the loop block is not executed at all, so semaphore-1. When the semaphore is equal to 0 after the loop 10, the thread will be blocked until the dispatch_semaphore_signal of the block is executed. will continue to execute

practical application

In development, we need to wait for a certain network callback before executing the following operations. According to the process of analysis for you, we can write the following code to achieve this effect.

_block BOOL isok = NO;  

    dispatch_semaphore_t sema = dispatch_semaphore_create(0);  
    Engine *engine = [[Engine alloc] init];  
    [engine queryCompletion:^(BOOL isOpen) {  
        isok = isOpen;  
        dispatch_semaphore_signal(sema);  
    } onError:^(int errorCode, NSString *errorMessage) {  
        isok = NO;  
        dispatch_semaphore_signal(sema);  
    }];  

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);  
    // todo what you want to do after net callback

To be more specific, when making an address book, you need to judge the authority to obtain the address book. if I recall it correctly. Before iOS9, it can be obtained in the following ways. This was also the first time I actually applied semaphores.
Get address book

//创建通讯簿的引用        
addBook=ABAddressBookCreateWithOptions(NULL, NULL);        //创建一个出事信号量为0的信号       
 dispatch_semaphore_t sema=dispatch_semaphore_create(0);        //申请访问权限       
 ABAddressBookRequestAccessWithCompletion(addBook, ^(bool greanted, CFErrorRef error)      
    {
            //greanted为YES是表示用户允许,否则为不允许           
 if (!greanted) {   
            tip=1;         
   }            //发送一次信号            dispatch_semaphore_signal(sema);  

     });        //等待信号触发     
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);





Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325388361&siteId=291194637