iOS筆記(一)GCD多線程:信號量和條件鎖

1.信號量 併發

dispatch_semaphore_t  async

在NSOperation中,能夠直接設置最大併發數來控制併發數量,在GCD中,控制併發數量由信號量來完成。函數

信號量是一個整形值而且具備一個初始計數值,而且支持兩個操做:信號通知和等待。當一個信號量被信號通知,其計數會被增長。當一個線程在一個信號量上等待時,線程會被阻塞(若是有必要的話),直至計數器大於零,而後線程會減小這個計數。
spa

  在GCD中有三個函數是semaphore的操做,分別是:線程

  dispatch_semaphore_create   建立一個semaphorecode

  dispatch_semaphore_signal   發送一個信號orm

  dispatch_semaphore_wait    等待信號對象

  簡單的介紹一下這三個函數,第一個函數有一個整形的參數,咱們能夠理解爲信號的總量,dispatch_semaphore_signal是發送一個信號,天然會讓信號總量加1,dispatch_semaphore_wait等待信號,當信號總量少於0的時候就會一直等待,不然就能夠正常的執行,並讓信號總量-1,根據這樣的原理,咱們即可以快速的建立一個併發控制來同步任務和有限資源訪問控制。遞歸

  //信號量:整數值,最多有10個線程併發    
  dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);       
  for (int i = 0; i < 100; i++)    
  {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            //當前信號量-1           
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);                       
            NSLog(@"%d",i+1);                       
            //線程休眠            
            //C           
            //sleep(1);            
            //OC            
            [NSThread sleepForTimeInterval:1];                       
            //當前信號量+1            
            dispatch_semaphore_signal(semaphore);                   
            });
    }

阻塞線程:資源

/**阻塞線程*/
// 建立一個信號量,值爲0    
dispatch_semaphore_t sema = dispatch_semaphore_create(0);    
// 在一個操做結束後發信號,這會使得信號量+1    
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error)
  {           
     dispatch_semaphore_signal(sema);           
  });    
// 一開始執行到這裏信號量爲0,線程被阻塞,直到上述操做完成使信號量+1,線程解除阻塞
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);



2.條件鎖 

條件鎖能夠控制線程的執行次序,至關於NSOperation中的依賴關係

/*     常見的鎖:    
        1.@synchronized(對象) 對象鎖     
        2.NSLock 互斥鎖     
        3.NSConditionLock 條件鎖         
        NSRecursiveLock 遞歸鎖     
        */    
        //條件鎖,條件是整數值    
        NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:3];       
        //不要在外面加鎖,那樣鎖的是主線程    
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
                 //加鎖        
                 [lock lockWhenCondition:3];               
                 NSLog(@"111111111111");               
                 //解鎖        
                 [lock unlockWithCondition:4];           
                 });       
                 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{               
                 //加鎖        
                 [lock lockWhenCondition:4];               
                 NSLog(@"222222222222");               
                 //解鎖        
                 [lock unlock];       
    });
相關文章
相關標籤/搜索