freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

ios平臺下并發(fā)編程的研究和實現(xiàn)畢業(yè)論文-閱讀頁

2025-08-11 08:25本頁面
  

【正文】 程效率高,但是創(chuàng)建block和在隊列中執(zhí)行仍然需要一定的開銷,如果某個塊執(zhí)行的任務(wù)量很小,直接調(diào)用它可能要比在隊列中執(zhí)行好一些。4. 不要試圖緩存一些與底層線程有關(guān)的數(shù)據(jù),以望另一個不同的block能夠更容易獲取這些數(shù)據(jù)。5. 如過程序中的block創(chuàng)建了很多的ObjectiveC對象,可能需要把這些代碼括在autorelease block中來管理內(nèi)存。如果程序可用的內(nèi)存比較緊張,創(chuàng)建自己的自動引用計數(shù)池。調(diào)度隊列能夠串行或并行執(zhí)行任務(wù)。下面將介紹如何創(chuàng)建和使用調(diào)度隊列。并發(fā)隊列仍然是先進(jìn)先出的隊列,然而,也有可能后添加的任務(wù)會比先添加的任務(wù)完成并出隊。許多因素會影響全局隊列的并發(fā)數(shù),包括處理器核心,其他進(jìn)行執(zhí)行任務(wù)的數(shù)量,以及其他串行隊列中任務(wù)的數(shù)量以及優(yōu)先級[6]。如下:dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORTITY_DEFAULT,0)。需要注意的是,第二個參數(shù)是為了以后使用而預(yù)留的,現(xiàn)在傳入0即可。因此,不要持有它們的引用,僅僅當(dāng)需要時直接調(diào)用即可。很多時候可能需要使用串行隊列來代替鎖的操作,或者保護(hù)共享的資源以及其他的數(shù)據(jù)結(jié)構(gòu)。跟并發(fā)隊列也不一樣,必須顯示地創(chuàng)建和管理需要使用的串行隊列,在程序中可以創(chuàng)建任意數(shù)量的串行隊列,但是要避免通過創(chuàng)建大量的串行隊列以達(dá)到同時執(zhí)行任務(wù)的想法。當(dāng)創(chuàng)建串行隊列時,可以為每一個隊列標(biāo)識一個符號,這樣子在調(diào)試時可以更加清晰,因為調(diào)試時會顯示出串行隊列的標(biāo)識符。dispatch_queue_t queue。除了自己創(chuàng)建的串行隊列,系統(tǒng)也自動創(chuàng)建了一條串行隊列,并將其綁定在應(yīng)用程序主線程上。使用dispatch_get_main_queue獲取程序主線程對應(yīng)的串行隊列,這個隊列是系統(tǒng)自動創(chuàng)建的,調(diào)用dispatch_main函數(shù)或者配置RunLoop在主線程上。調(diào)度隊列和其他dispatch對象都是引用計數(shù)類型。retain和release dispatch對象是特別重要的,例如為了確保隊列使用時仍存在于內(nèi)存中,作為Cocoa內(nèi)存管理的對象,基本的守則是如果在代碼中打算使用,那么用之前retain用完release。即使實現(xiàn)了垃圾回收的程序,仍然需要retain和release調(diào)度隊列,因為GCD不支持垃圾回收。為了設(shè)置或獲取給定對象的數(shù)據(jù),可使用dispatch_set_context和dispatch_get_context函數(shù),系統(tǒng)任何時候都不會使用這些自定義的數(shù)據(jù),并且適時申請和釋放這些數(shù)據(jù)都是開發(fā)者的責(zé)任??梢允褂藐犃械慕Y(jié)束方法在隊列本身釋放前釋放上下文數(shù)據(jù)。調(diào)度隊列是引用計數(shù)的對象,可以使用dispatch_set_finalizer_f方法來指定函數(shù),當(dāng)引用計數(shù)為零時被調(diào)用。下面展示了一個自定義的結(jié)束方法:void myFinalizerFunction(void *context){ myDataContext* theData = (MyDataContext *)context。 // 釋放 free(theData)。 myInitializeDataContextfuction(data)。 if (serialQueue) { dispatch_set_context(serialQueue, data)。myFinalizerFunction)。}為了執(zhí)行任務(wù),必須將其添加到調(diào)度隊列中,可以使用同步或異步的方式,也可以單個或成組的調(diào)度。本章節(jié)展示一些調(diào)度任務(wù)的技術(shù),并介紹了各自的優(yōu)點。如果可能的話,使用dispatch_async和dispatch_async_f函數(shù)的異步方案要優(yōu)于同步的代碼,在向隊列中添加任務(wù)后,還沒有辦法知道具體開始執(zhí)行的時間。盡管應(yīng)該盡可能添加異步的任務(wù),但是有的時候,需要添加同步任務(wù)以避免競爭條件或其他一些同步的錯誤,在這些情況下,可以使用dispatch_sync和dispatch_sync_f函數(shù)。永遠(yuǎn)不應(yīng)該調(diào)用同步任務(wù)到你需要執(zhí)行任務(wù)的線程,因為這樣可能會造成死鎖。下面的例子演示了如何同步或異步執(zhí)行基于 block 的變體:dispatch_queue_t myCustomQueue。dispatch_async(myCustomQueue, ^{ printf(Do some work here.\n)。printf(The first block may or may not have run.\n)。})。 block實際上,任務(wù)在隊列中獨立地執(zhí)行,然而當(dāng)任務(wù)完成時,程序可能仍然想知道結(jié)果。pletion block僅僅只是在調(diào)度任務(wù)時添加在尾部的代碼塊。下面展示了一種常見的用法:void average_async(int *data, size_t len, dispatch_queue_t queue, void (^block)(int)){ // Retain 隊列以保證當(dāng)pletion block被取消時隊列仍然在內(nèi)存中 dispatch_retain(queue)。 dispatch_async(queue, ^{ block(avg)。 // 當(dāng)用戶提供的block完成時release隊列 dispatch_release(queue)。}另一種并發(fā)隊列特別有用的地方是循環(huán)迭代計算,例如,可能使用for循環(huán)做一些計算。雖然在調(diào)用函數(shù)時可以使用串行隊列,但是這種做法完全沒有必要,因為沒有什么性能上的優(yōu)勢[9]。因此,你應(yīng)當(dāng)在隊列的上下文中執(zhí)行時小心一些,如果傳遞的參數(shù)是串行隊列,那么有可能造成死鎖。例如下面這個用dispatch_apply替換for循環(huán)的例子:dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)。})。如果每次循環(huán)迭代的任務(wù)量很小,那么這些開銷會讓替代循環(huán)變得得不償失。如果不想創(chuàng)建Cocoa程序,而且不想顯示地設(shè)置RunLoop,那么必須調(diào)用dispatch_main方法drain主線程,當(dāng)然也可以添加任務(wù)到這個隊列,但是它不會執(zhí)行,直到調(diào)用這個方法。GCD對Cocoa內(nèi)存管理提供了內(nèi)建的支持,因此可以在提交到隊列的block中輕松的使用ObjectiveC對象。如果程序可用的內(nèi)存吃緊或block創(chuàng)建了很多自動釋放的對象,創(chuàng)建自己的自動引用池是唯一的辦法來確保對象適時的release??梢酝ㄟ^掛起隊列來暫停block的執(zhí)行,使用dispatch_suspend函數(shù)掛起隊列,并增加隊列暫停引用計數(shù);使用dispatch_resume函數(shù)繼續(xù)隊列的執(zhí)行,并減少其引用計數(shù)。因此必須保持平衡,使所有的暫停操作都有匹配的恢復(fù)操作。如果提交到隊列中的任務(wù)需要訪問一些有限的資源,可能需要使用dispatch信號量來控制同時訪問資源的任務(wù)數(shù)量。因為GCD在這種特殊情況下并不會調(diào)用內(nèi)核。使用調(diào)度信號量的語法如下:1. 當(dāng)創(chuàng)建調(diào)度信號量時(使用dispatch_semaphore_create函數(shù)),可以指定一個絕對值來表示當(dāng)前可使用的資源數(shù)量。3. 當(dāng)?shù)却{(diào)用返回時,使用資源繼續(xù)工作。為了描述這些步驟,舉一個使用文件描述符的例子??墒褂眯盘柫縼硖幚磉@種問題,下面是一些基本的代碼:// 創(chuàng)建信號量,初始化可用的文件描述符數(shù)量dispatch_semaphore_t fd_sema = dispatch_semaphore_create(getdtablesize() / 2)。fd = open(/etc/services, O_RDONLY)。dispatch_semaphore_signal(fd_sema)。另一種使用方式是作為線程同步的替代方案,如果打算使用多個子線程并且同步執(zhí)行它們,那么可以將它們對應(yīng)的任務(wù)添加到dispatch group中并等待整個group完成[11]。// 創(chuàng)建全局隊列dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)。// 添加任務(wù)進(jìn)組dispatch_group_async(group, queue, ^{ // 處理一些異步的任務(wù)})。// 完成工作后釋放這個組dispatch_release(group)。2. 不要在dispatch_async中傳入當(dāng)前隊列,并且調(diào)用這個任務(wù),這會阻塞當(dāng)前線程,即不要在當(dāng)前線程中執(zhí)行同步操作。第五章 調(diào)度源每當(dāng)與系統(tǒng)底層進(jìn)行交互時,必須要做好這種任務(wù)的執(zhí)行可能會消耗大量時間的準(zhǔn)備。因為這些原因,許多系統(tǒng)的庫都提供了異步的API,允許代碼向系統(tǒng)提交請求后繼續(xù)做別的工作,這時請求仍在進(jìn)行中。 Source介紹Dispatch Source是協(xié)調(diào)底層特殊系統(tǒng)事件的基本類型。2. 信號dispatch source:當(dāng) UNIX信號到達(dá)時通知。4. 進(jìn)程dispatch source:通知一些有關(guān)進(jìn)程的事件,例如:進(jìn)程存在時、進(jìn)程發(fā)出 fork 或者 exec 類型的調(diào)用以及當(dāng)信號送達(dá)進(jìn)程時。6. 自定義dispatch source:自定義和自觸發(fā)的事件。在配置一個 調(diào)度源時,需要指定想要監(jiān)聽的事件、調(diào)度隊列以及用于處理事件的代碼。當(dāng)監(jiān)聽的事件到達(dá)時,調(diào)度源提交block或函數(shù)到指定的隊列中去執(zhí)行。調(diào)度源保持附加在其隊列上,除非你顯式地取消它。比如一些定時器事件,這種事件周期性地發(fā)生,但大多數(shù)時間會發(fā)生在某些特定的狀態(tài)下。為了防止隊列中事件太多發(fā)生積壓,調(diào)度源實現(xiàn)了一種合并機制。根據(jù)事件類型的不同,合并的結(jié)果可能是取代舊事件或者更新信息。 Source在創(chuàng)建調(diào)度源時除創(chuàng)建它本身以外還需要創(chuàng)建事件源,事件源就是處理事件需要的本地數(shù)據(jù)結(jié)構(gòu)?;谶M(jìn)程的源,需要獲取目標(biāo)程序的進(jìn)程ID。2. 配置調(diào)度源: a) 給它分配一個事件處理操作;b) 對于定時器源,使用dispatch_source_set_timer函數(shù)設(shè)置定時器信息。4. 調(diào)用dispatch_resume函數(shù)來開始處理事件。在掛起時,它接收事件但是不做處理。下面幾部分介紹了如何配置 dispatch source。事件處理操作可以是一個函數(shù)或者block,然后可以用dispatch_source_set_event_handler或 dispatch_source_set_event_handler_f 函數(shù)進(jìn)行設(shè)置。事件處理操作需要處理所有可能到達(dá)的事件,如果事件處理操作已經(jīng)在處理中,并且等待下一個事件。事件處理操作通??雌饋硪恢碧幚碜钚碌牟僮鳎鋵嵑芸赡芴幚淼氖嵌鄠€事件的合并版本?;诤瘮?shù)的事件處理操作采用單個上下文指針,包含調(diào)度源對象,并且不返回任何值。// 基于block的事件處理操作void (^dispatch_block_t)(void)// 基于函數(shù)的時間處理操作void (*dispatch_function_t)(void *)在事件處理操作中,可以從調(diào)度源提供的事件中獲取事件的相應(yīng)信息。例如下面的程序段:// 創(chuàng)建調(diào)度源dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, myDescriptor, 0 ,myQueue)。// 繼續(xù)相關(guān)操作})。盡管block提供了可以修改變量的功能,但是最好不要去嘗試使用。下面列出了可以在事件處理程序中獲取有關(guān)事件信息的函數(shù)[15]。對于描述符源,返回int類型,包含其對應(yīng)的描述符;對于信號源,返回int類型,包含最近事件的信號數(shù)量;對于進(jìn)程源,返回pid_t類型的數(shù)據(jù)結(jié)構(gòu),對應(yīng)于被監(jiān)控的進(jìn)程;對于Mach端口源,返回mach_port_t數(shù)據(jù)結(jié)構(gòu);對于其他源,其返回值是不明確的。對于Mach端口源,返回dispatch_source_machport_flags_t枚舉類型,指示事件類型; 對于自定義源,返回由dispatch_source_merge_data函數(shù)合并現(xiàn)值和新值后創(chuàng)建的合并值。對于進(jìn)程,返回 dispatch source 收到事件的掩碼,參照dispatch_source_proc_flags_t枚舉類型;對于Mach端口,返回期望事件的掩碼,參照dispatch_source_mach_send_flags_t枚舉類型;對于自定義類型,返回用于合并數(shù)據(jù)的掩碼。多數(shù)類型的調(diào)度源不需要取消處理操作,除非對調(diào)度源有自定義的行為并且需要在釋放時執(zhí)行。否則可能導(dǎo)致Bug,因為這些結(jié)構(gòu)體會被系統(tǒng)其他部分或應(yīng)用程序在不經(jīng)意間重用。使用dispatch_source_set_cancel_handler或dispatch_source_set_cancel_handler_f函數(shù)來設(shè)置取消處理操作。 })。不過也可以使用dispatch_set_target_queue函數(shù)在任何時候修改目標(biāo)隊列。修改調(diào)度源是異步操作,也就是說已經(jīng)執(zhí)行的事件不會對其造成影響。和GCD的其他類型一樣,可以使用dispatch_set_context函數(shù)關(guān)聯(lián)自定義數(shù)據(jù)到調(diào)度源。在存儲數(shù)據(jù)之后,就必須要加入取消處理器,因為需要在取消操作中釋放context中的自定義數(shù)據(jù)。雖然這樣可以代替context指針,但是應(yīng)該謹(jǐn)慎地使用這種方式。不管哪一種方式,都需要提供一個取消處理器來釋放這些已經(jīng)持有的數(shù)據(jù)[16]。當(dāng)引用計數(shù)為0時,系統(tǒng)自動釋放調(diào)度源數(shù)據(jù)結(jié)構(gòu)。使用外部所有權(quán)時,另一個對象擁有調(diào)度源,并負(fù)責(zé)在適當(dāng)?shù)臅r候釋放。例如調(diào)度源應(yīng)用于單一全局事件時
點擊復(fù)制文檔內(nèi)容
高考資料相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1