2019-09-27

iOS信號量

信號量的本質(zhì):

信號量的本質(zhì)是數(shù)據(jù)操作鎖, 它本身不具有數(shù)據(jù)交換的功能,而是通過控制其他的通信資源來實現(xiàn)進程間通信,它本身只是一種外部資源的標識懈词。信號量在此過程中負責數(shù)據(jù)操作的互斥蜻势、同步等功能.

信號量的工作原理

由于信號量只能進行兩種操作等待和發(fā)送信號,即P(sv)和V(sv),他們的行為是這樣的:

P(sv):如果sv的值大于零,就給它減1雷滚;如果它的值為零,就掛起該進程的執(zhí)行

V(sv):如果有其他進程因等待sv而被掛起吗坚,就讓它恢復(fù)運行祈远,如果沒有進程因等待sv而掛起,就給它加1.

舉個例子刻蚯,就是 兩個進程共享信號量sv绊含,一旦其中一個進程執(zhí)行了P(sv)操作,它將得到信號量炊汹,并可以進入臨界區(qū)躬充,使sv減1。而第二個進程將被阻止進入臨界區(qū)讨便,因為 當它試圖執(zhí)行P(sv)時充甚,sv為0,它會被掛起以等待第一個進程離開臨界區(qū)域并執(zhí)行V(sv)釋放信號量霸褒,這時第二個進程就可以恢復(fù)執(zhí)行伴找。

信號量的三個函數(shù)是:

dispatch_semaphore_create(long value); // 創(chuàng)建一個semaphore
dispatch_semaphore_signal(dispatch_semaphore_t dsema); // 發(fā)送一個信號
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout); // 等到信號

舉幾個例子,代碼如下:

-(void)dispatch_group_function1
{
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.baidu.com"]];
        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            // 請求完成废菱,可以通知界面刷新界面等操作
            NSLog(@"第一步網(wǎng)絡(luò)請求完成");
            // 使信號的信號量+1技矮,這里的信號量本來為0,+1信號量為1(綠燈)
            dispatch_semaphore_signal(semaphore);
        }];
        [task resume];
        // 以下還要進行一些其他的耗時操作
        NSLog(@"耗時操作1繼續(xù)進行");
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    });
    dispatch_group_async(group, dispatch_queue_create("com.dispatch.test", DISPATCH_QUEUE_CONCURRENT), ^{
        NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://www.github.com"]];
        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            // 請求完成殊轴,可以通知界面刷新界面等操作
            NSLog(@"第二步網(wǎng)絡(luò)請求完成");
            // 使信號的信號量+1衰倦,這里的信號量本來為0,+1信號量為1(綠燈)
            dispatch_semaphore_signal(semaphore);
        }];
        [task resume];
        // 以下還要進行一些其他的耗時操作
        NSLog(@"耗時操作2繼續(xù)進行");
        dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"刷新界面等在主線程的操作");
    });
}

首先旁理,默認初始值給的信號量值未0樊零,所以線程1和線程2的執(zhí)行上其實是沒有順序的,但是孽文,由于在這里設(shè)置了dispatch_semaphore_wait驻襟,并且當前的信號量值未0夺艰,所以會堵塞線程,直到執(zhí)行了dispatch_semaphore_signal信號量+1沉衣,才會繼續(xù)執(zhí)行之后的線程操作郁副,打印結(jié)果為:

2019-09-27 15:02:51.420389+0800 CPTestDemo[5253:337990] 耗時操作2繼續(xù)進行
2019-09-27 15:02:51.420414+0800 CPTestDemo[5253:337992] 耗時操作1繼續(xù)進行
2019-09-27 15:02:51.544547+0800 CPTestDemo[5253:338000] 第一步網(wǎng)絡(luò)請求完成
2019-09-27 15:02:53.100889+0800 CPTestDemo[5253:337995] 第二步網(wǎng)絡(luò)請求完成
2019-09-27 15:02:53.101065+0800 CPTestDemo[5253:337950] 刷新界面等在主線程的操作

如果初始值設(shè)置dispatch_semaphore_create(1),又會是怎樣的結(jié)果的

2019-09-27 15:05:34.816451+0800 CPTestDemo[5302:345432] 耗時操作1繼續(xù)進行
2019-09-27 15:05:34.816451+0800 CPTestDemo[5302:345433] 耗時操作2繼續(xù)進行
2019-09-27 15:05:34.926754+0800 CPTestDemo[5302:345437] 第一步網(wǎng)絡(luò)請求完成
2019-09-27 15:05:34.926966+0800 CPTestDemo[5302:345393] 刷新界面等在主線程的操作
2019-09-27 15:05:36.475560+0800 CPTestDemo[5302:345437] 第二步網(wǎng)絡(luò)請求完成

如果初始值設(shè)置dispatch_semaphore_create(2)呢

2019-09-27 15:27:59.737338+0800 CPTestDemo[5587:373223] 耗時操作1繼續(xù)進行
2019-09-27 15:27:59.737338+0800 CPTestDemo[5587:373222] 耗時操作2繼續(xù)進行
2019-09-27 15:27:59.758308+0800 CPTestDemo[5587:373190] 刷新界面等在主線程的操作
2019-09-27 15:27:59.880029+0800 CPTestDemo[5587:373220] 第一步網(wǎng)絡(luò)請求完成
2019-09-27 15:28:01.847547+0800 CPTestDemo[5587:373220] 第二步網(wǎng)絡(luò)請求完成

因為信號量初始值為2厢蒜,線程1和2都會執(zhí)行霞势,由于執(zhí)行完成信號量減為0,但是組中的任務(wù)已經(jīng)執(zhí)行完了斑鸦,所以會接著執(zhí)行dispatch_group_notify愕贡,然后依次是第一步網(wǎng)絡(luò)請求和第二步網(wǎng)絡(luò)請求

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市巷屿,隨后出現(xiàn)的幾起案子固以,更是在濱河造成了極大的恐慌,老刑警劉巖嘱巾,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件憨琳,死亡現(xiàn)場離奇詭異,居然都是意外死亡旬昭,警方通過查閱死者的電腦和手機篙螟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來问拘,“玉大人遍略,你說我怎么就攤上這事≈枳” “怎么了绪杏?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長纽绍。 經(jīng)常有香客問我蕾久,道長,這世上最難降的妖魔是什么拌夏? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任僧著,我火速辦了婚禮,結(jié)果婚禮上障簿,老公的妹妹穿的比我還像新娘盹愚。我一直安慰自己,他們只是感情好卷谈,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著霞篡,像睡著了一般世蔗。 火紅的嫁衣襯著肌膚如雪端逼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天污淋,我揣著相機與錄音顶滩,去河邊找鬼。 笑死寸爆,一個胖子當著我的面吹牛礁鲁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播赁豆,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼仅醇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了魔种?” 一聲冷哼從身側(cè)響起析二,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎节预,沒想到半個月后叶摄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡安拟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年蛤吓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片糠赦。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡会傲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愉棱,到底是詐尸還是另有隱情唆铐,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布奔滑,位于F島的核電站艾岂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏朋其。R本人自食惡果不足惜王浴,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梅猿。 院中可真熱鬧氓辣,春花似錦、人聲如沸袱蚓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至体斩,卻和暖如春梭稚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背絮吵。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工弧烤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹬敲。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓暇昂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親伴嗡。 傳聞我的和親對象是個殘疾皇子急波,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 本文用來介紹 iOS 多線程中 GCD 的相關(guān)知識以及使用方法。這大概是史上最詳細闹究、清晰的關(guān)于 GCD 的詳細講...
    花花世界的孤獨行者閱讀 497評論 0 1
  • 1.NSTimer不準時的原因:(1).RunLoop循環(huán)處理時間幔崖,每次循環(huán)是固定時間,只有在這段時間才會去查看N...
    稻春閱讀 1,233評論 0 3
  • 鎖是一種同步機制渣淤,用于多線程環(huán)境中對資源訪問的限制iOS中常見鎖的性能對比圖(摘自:ibireme): iOS鎖的...
    LiLS閱讀 1,510評論 0 6
  • 在iOS開發(fā)的道路上,多線程的重要性不言而喻. 大部分我們都停留在基礎(chǔ)的使用上面.缺乏高級應(yīng)用. 缺乏提升,是因為...
    瘋狂的木頭人閱讀 1,137評論 0 1
  • 你們經(jīng)歷了高三赏寇,但是它對于你們來說并不是黑色的,只是一種比平時緊張的感覺而已价认,在內(nèi)心深處你們還沒有真正意義上體會到...
    16aa5fab5f62閱讀 186評論 0 1