線程管理(iOS)

OS X 或iOS中的每個(gè)進(jìn)程(應(yīng)用程序)由一個(gè)或者多個(gè)線程組成,每個(gè)線程應(yīng)用程序的代碼表示單個(gè)執(zhí)行路徑。
每個(gè)應(yīng)用程序都從單個(gè)線程開(kāi)始,它運(yùn)行應(yīng)用程序的main功能。 應(yīng)用程序可以生成額外的線程,每個(gè)線程都執(zhí)行特定功能的代碼。

當(dāng)應(yīng)用程序產(chǎn)生一個(gè)新線程時(shí),該線程將成為應(yīng)用程序進(jìn)程空間內(nèi)的獨(dú)立實(shí)體。 每個(gè)線程都有自己的執(zhí)行堆棧,并由內(nèi)核分別安排運(yùn)行。 線程可以與其他線程和其他進(jìn)程進(jìn)行通信,執(zhí)行I / O操作,還可以執(zhí)行任何您可能需要執(zhí)行的操作。 因?yàn)樗鼈冊(cè)谙嗤倪M(jìn)程空間內(nèi),所以單個(gè)應(yīng)用程序中的所有線程共享相同的虛擬內(nèi)存空間,并具有與進(jìn)程本身相同的訪問(wèn)權(quán)限。

本章概述了OS X和iOS中可用的線程技術(shù),以及如何在應(yīng)用程序中使用這些技術(shù)的示例。

線程成本

線程在內(nèi)存使用和性能方面對(duì)您的程序(和系統(tǒng))有實(shí)際的成本。 每個(gè)線程需要在內(nèi)核內(nèi)存空間和程序的內(nèi)存空間中分配內(nèi)存。 管理線程和協(xié)調(diào)其調(diào)度所需的核心結(jié)構(gòu)使用有線內(nèi)存存儲(chǔ)在內(nèi)核中。 您的線程的堆??臻g和每個(gè)線程數(shù)據(jù)存儲(chǔ)在程序的內(nèi)存空間中。 當(dāng)您首次創(chuàng)建線程時(shí),大多數(shù)這些結(jié)構(gòu)都將被創(chuàng)建和初始化 - 由于與內(nèi)核所需的交互,這個(gè)進(jìn)程可能相對(duì)昂貴。

表1量化了在應(yīng)用程序中創(chuàng)建新的用戶(hù)級(jí)線程所需的大概成本。 這些成本中的一些是可配置的,例如為次要線程分配的堆??臻g量。 創(chuàng)建線程的時(shí)間成本是一個(gè)粗略的近似值,只能用于相互比較。 線程創(chuàng)建時(shí)間可能因處理器負(fù)載,計(jì)算機(jī)速度以及可用系統(tǒng)和程序存儲(chǔ)器的數(shù)量而異。

表1

項(xiàng)目 大概花費(fèi) 描述
內(nèi)核數(shù)據(jù)結(jié)構(gòu) 大約1 KB 該內(nèi)存用于存儲(chǔ)線程數(shù)據(jù)結(jié)構(gòu)和屬性,其中大部分被分配為有線內(nèi)存,因此不能被分頁(yè)到磁盤(pán)。
堆??臻g 512 KB(二級(jí)線程)8 MB(OS X主線程)1 MB(iOS主線程) 輔助線程的最小允許堆棧大小為16 KB,堆棧大小必須為4 KB的倍數(shù)。 這個(gè)內(nèi)存的空間在線程創(chuàng)建時(shí)被放在你的進(jìn)程空間中,但是在需要的時(shí)候才會(huì)創(chuàng)建與該內(nèi)存關(guān)聯(lián)的實(shí)際頁(yè)面。
創(chuàng)建時(shí)間 大約90微秒 此值反映了初始調(diào)用創(chuàng)建線程與線程入口點(diǎn)例程開(kāi)始執(zhí)行的時(shí)間。 這些數(shù)字是通過(guò)分析在基于Intel的iMac上使用2 GHz Core Duo處理器和1 GB RAM運(yùn)行OS X v10.5的線程創(chuàng)建過(guò)程中生成的平均值和中值。

注意:由于它們的底層內(nèi)核支持,操作對(duì)象通常可以更快地創(chuàng)建線程。 他們每次都從頭開(kāi)始創(chuàng)建線程,而是使用已經(jīng)駐留在內(nèi)核中的線程池來(lái)節(jié)省分配時(shí)間。

編寫(xiě)線程代碼時(shí)需要考慮的另一個(gè)代價(jià)是生產(chǎn)成本。 設(shè)計(jì)線程應(yīng)用程序有時(shí)可能需要對(duì)組織應(yīng)用程序數(shù)據(jù)結(jié)構(gòu)的方式進(jìn)行根本性更改。 進(jìn)行這些更改可能是必要的,以避免使用同步,這本身可能對(duì)設(shè)計(jì)不當(dāng)?shù)膽?yīng)用程序造成巨大的性能損失。 設(shè)計(jì)這些數(shù)據(jù)結(jié)構(gòu)和線程代碼中的調(diào)試問(wèn)題,可以增加開(kāi)發(fā)線程應(yīng)用程序所花費(fèi)的時(shí)間。 避免這些費(fèi)用可能會(huì)在運(yùn)行時(shí)產(chǎn)生更大的問(wèn)題,但是,如果你的線程花費(fèi)太多時(shí)間等待鎖或什么都不做。

創(chuàng)建線程

創(chuàng)建低級(jí)線程比較簡(jiǎn)單。 在所有情況下,您必須具有一個(gè)函數(shù)或方法作為線程的主要入口點(diǎn),并且您必須使用一個(gè)可用的線程例程來(lái)啟動(dòng)您的線程。 以下部分顯示了更常用的線程技術(shù)的基本創(chuàng)建過(guò)程。 使用這些技術(shù)創(chuàng)建的線程將繼承一組默認(rèn)屬性,由您使用的技術(shù)確定。

使用NSThread

使用NSthread類(lèi)創(chuàng)建一個(gè)線程有兩種方法:

  • 使用 datachNewThreadSelector:toTarget:withoutObject:方法來(lái)生成新線程。

  • 創(chuàng)建一個(gè)新的Thread 對(duì)象并調(diào)用其start方法。
    這兩種技術(shù)在您的應(yīng)用程序中創(chuàng)建一個(gè)分離的線程。 分離的線程意味著當(dāng)線程退出時(shí),線程的資源將被系統(tǒng)自動(dòng)回收。 這也意味著您的代碼不必在以后明確加入該線程。

因?yàn)樵谒邪姹镜腛S X中都支持detachNewThreadSelector:toTarget:withObject: method,所以在現(xiàn)有Cocoa應(yīng)用程序中通常會(huì)使用線程。 要分離一個(gè)新線程,只需提供要用作線程入口點(diǎn)的方法(指定為選擇器)的名稱(chēng),定義該方法的對(duì)象以及要在啟動(dòng)時(shí)傳遞給線程的任何數(shù)據(jù)。 以下示例顯示了使用當(dāng)前對(duì)象的自定義方法生成線程的此方法的基本調(diào)用。

[NSThread detachNewThreadSelector:@selector(myThreadMainMethod :) toTarget:self withObject:nil];

在OS X v10.5之前,您主要使用NSThread
類(lèi)來(lái)生成線程。 雖然可以獲得一個(gè)NSThread
對(duì)象并訪問(wèn)一些線程屬性,但是您只能在線程本身運(yùn)行后才能執(zhí)行此操作。 在OS X v10.5中,添加了創(chuàng)建NSThread
對(duì)象的支持,而不會(huì)立即產(chǎn)生相應(yīng)的新線程。 (此支持也可在iOS中使用。)此支持可以在啟動(dòng)線程之前獲取和設(shè)置各種線程屬性。 它也可以使用該線程對(duì)象稍后引用正在運(yùn)行的線程。
在OS X v10.5及更高版本中初始化NSThread
對(duì)象的簡(jiǎn)單方法是使用[initWithTarget:selector:object:]
method。 此方法與detachNewThreadSelector:toTarget:withObject:
method完全相同的信息,并使用它來(lái)初始化新的NSThread
實(shí)例。 但是,它不啟動(dòng)線程。 要啟動(dòng)線程,您將顯式調(diào)用線程對(duì)象的start方法,如以下示例所示:

 NSThread * myThread = [[NSThread alloc] initWithTarget:self 
  selector:@selector(myThreadMainMethod :) 
 對(duì)象:nil]; 
  [myThread start]; 

注意:使用initWithTarget:selector:object:方法的initWithTarget:selector:object:一種方法是將NSThread子類(lèi)化并覆蓋其main方法。 您將使用此方法的覆蓋版本來(lái)實(shí)現(xiàn)線程的主入口點(diǎn)。

如果您的線程當(dāng)前正在運(yùn)行的NSThread
對(duì)象,您可以向該線程發(fā)送消息的一種方法是使用應(yīng)用程序中幾乎任何對(duì)象的`[performSelector:onThread:withObject:waitUntilDone:]
方法。 在線程上執(zhí)行的選擇器支持(主線程除外)在OS X v10.5中引入,是一種方便的線程通信方式。 (此支持也可在iOS中使用。)使用此技術(shù)發(fā)送的消息由另一個(gè)線程直接執(zhí)行,作為其正常運(yùn)行循環(huán)處理的一部分。 (當(dāng)然,這意味著目標(biāo)線程必須在其運(yùn)行循環(huán)中運(yùn)行)當(dāng)您以這種方式進(jìn)行通信時(shí),您可能仍需要某種形式的同步,但它比在線程。

注意:盡管線程之間的偶爾通信很有用,但不應(yīng)該使用performSelector:onThread:withObject:waitUntilDone:
方法來(lái)對(duì)線程之間進(jìn)行時(shí)間關(guān)鍵或頻繁的通信。

使用NSObject生成線程

在iOS和OS X v10.5及更高版本中,所有對(duì)象都有能力產(chǎn)生一個(gè)新的線程并使用它來(lái)執(zhí)行其中的一個(gè)方法。[performSelectorInBackground:withObject:]
method創(chuàng)建一個(gè)新的脫機(jī)線程,并使用指定的方法作為新線程的入口點(diǎn)。 例如,如果您有一些對(duì)象(由變量myObj
),并且該對(duì)象具有要在后臺(tái)線程中運(yùn)行的名為doSomething
的方法,則可以使用以下代碼:

[myObj performSelectorInBackground:@selector(doSomething)withObject:nil];

調(diào)用此方法的效果與調(diào)用當(dāng)前對(duì)象,選擇器和參數(shù)對(duì)象作為參數(shù)的[NSThread][detachNewThreadSelector:toTarget:withObject:]
方法一樣。 使用默認(rèn)配置立即生成新線程,并開(kāi)始運(yùn)行。 在選擇器中,您必須像線程一樣配置線程。 例如,您將需要設(shè)置一個(gè)自動(dòng)釋放池(如果您沒(méi)有使用垃圾回收),并且如果您計(jì)劃使用它,則配置該線程的運(yùn)行循環(huán)。

配置線程屬性

創(chuàng)建線程后,有時(shí),您可能需要配置線程環(huán)境的不同部分。 以下部分介紹您可以進(jìn)行的一些更改以及何時(shí)進(jìn)行更改。

配置線程的堆棧大小

對(duì)于您創(chuàng)建的每個(gè)新線程,系統(tǒng)將在進(jìn)程空間中分配一定量的內(nèi)存,以充當(dāng)該線程的堆棧。 堆棧管理堆棧幀,也是線程的任何局部變量被聲明的地方。 為線程分配的內(nèi)存量列在線程成本中。
如果要更改給定線程的堆棧大小,則必須先創(chuàng)建線程。 所有線程技術(shù)都提供了一些設(shè)置堆棧大小的方法,盡管使用NSThread
設(shè)置堆棧大小只能在iOS和OS X v10.5及更高版本中使用。 表2列出了各種技術(shù)的不同選項(xiàng)。

表2.png
配置線程本地存儲(chǔ)

每個(gè)線程都維護(hù)一個(gè)鍵值對(duì)的字典,可以從線程中的任何位置訪問(wèn)。 您可以使用此字典來(lái)存儲(chǔ)在執(zhí)行線程期間要保留的信息。 例如,您可以使用它來(lái)存儲(chǔ)要通過(guò)線程的運(yùn)行循環(huán)的多次迭代來(lái)保持的狀態(tài)信息。
Cocoa和POSIX以不同的方式存儲(chǔ)線程字典,所以您不能混合和匹配兩種技術(shù)的調(diào)用。 只要您在線程代碼中使用一種技術(shù),最終結(jié)果應(yīng)該是相似的。 在Cocoa中,您可以使用NSThread對(duì)象的threadDictionary方法來(lái)檢索NSMutableDictionary對(duì)象,您可以向其中添加線程所需的任何鍵。 在POSIX中,您可以使用pthread_setspecificpthread_getspecific函數(shù)來(lái)設(shè)置和獲取線程的鍵值。

設(shè)置線程的分離狀態(tài)

默認(rèn)情況下,大多數(shù)高級(jí)線程技術(shù)都會(huì)創(chuàng)建脫機(jī)線程。 在大多數(shù)情況下,分離的線程是首選的,因?yàn)樗鼈冊(cè)试S系統(tǒng)在線程完成后立即釋放線程的數(shù)據(jù)結(jié)構(gòu)。 分離的線程也不需要與程序的明確交互。 從線程檢索結(jié)果的方法由您自行決定。 相比之下,系統(tǒng)不會(huì)回收可連接線程的資源,直到另一個(gè)線程與該線程明確連接,這個(gè)進(jìn)程可能會(huì)阻止執(zhí)行連接的線程。

您可以將可連接線程視為類(lèi)似于子線程。 雖然它們?nèi)匀蛔鳛楠?dú)立線程運(yùn)行,但是可以由另一個(gè)線程加入可連接線程,然后才能由系統(tǒng)回收其資源。 可連接線程還提供了將數(shù)據(jù)從退出線程傳遞到另一個(gè)線程的顯式方法。 在它退出之前,可連接線程可以將數(shù)據(jù)指針或其他返回值傳遞給pthread_exit函數(shù)。 另一個(gè)線程可以通過(guò)調(diào)用pthread_join函數(shù)來(lái)聲明此數(shù)據(jù)。

重要提示:在應(yīng)用程序退出時(shí),分離的線程可以立即終止,但可連接的線程不能。 在允許進(jìn)程退出之前,必須連接每個(gè)可連接的線程。 因此,線程執(zhí)行不應(yīng)中斷的關(guān)鍵工作(例如將數(shù)據(jù)保存到磁盤(pán))時(shí),可以使用可加入的線程。

如果你想創(chuàng)建可連接的線程,唯一的方法是使用POSIX線程。 默認(rèn)情況下,POSIX將線程創(chuàng)建為可連接。 要將線程標(biāo)記為分離或可連接,請(qǐng)?jiān)趧?chuàng)建線程之前使用pthread_attr_setdetachstate函數(shù)修改線程屬性。 線程開(kāi)始后,您可以通過(guò)調(diào)用pthread_detach函數(shù)將可連接線程更改為分離的線程。 有關(guān)這些POSIX線程函數(shù)的更多信息,請(qǐng)參閱 pthread 手冊(cè)頁(yè)。

設(shè)置線程的優(yōu)先級(jí)

您創(chuàng)建的任何新線程都具有與之關(guān)聯(lián)的默認(rèn)優(yōu)先級(jí)。 內(nèi)核的調(diào)度算法在確定要運(yùn)行的線程時(shí)考慮線程優(yōu)先級(jí),優(yōu)先級(jí)更高的線程比具有較低優(yōu)先級(jí)的線程更可能運(yùn)行。 較高的優(yōu)先級(jí)不能保證線程的特定執(zhí)行時(shí)間,只要與較低優(yōu)先級(jí)的線程進(jìn)行比較時(shí),調(diào)度程序更有可能選擇它。

重要提示:將線程的優(yōu)先級(jí)保留為默認(rèn)值是一個(gè)好主意。 增加某些線程的優(yōu)先級(jí)也會(huì)增加低優(yōu)先級(jí)線程之間的饑餓的可能性。 如果您的應(yīng)用程序包含必須互相交互的高優(yōu)先級(jí)和低優(yōu)先級(jí)的線程,則低優(yōu)先級(jí)線程的饑餓可能會(huì)阻止其他線程并創(chuàng)建性能瓶頸。

如果你想修改線程優(yōu)先級(jí),Cocoa和POSIX都提供了一種方法。 對(duì)于Cocoa線程,可以使用NSThread的` [setThreadPriority:] class方法設(shè)置當(dāng)前正在運(yùn)行的線程的優(yōu)先級(jí)。 對(duì)于POSIX線程,可以使用pthread_setschedparam
函數(shù)。

寫(xiě)你的線程進(jìn)入進(jìn)程

在大多數(shù)情況下,線程的入口點(diǎn)進(jìn)程的結(jié)構(gòu)與其他平臺(tái)上的OS X相同。 您初始化您的數(shù)據(jù)結(jié)構(gòu),做一些工作或可選地設(shè)置一個(gè)運(yùn)行循環(huán),并在線程的代碼完成時(shí)清理。 根據(jù)您的設(shè)計(jì),編寫(xiě)入門(mén)程序時(shí)可能需要執(zhí)行一些額外的步驟。

創(chuàng)建自動(dòng)釋放池

在Objective-C框架中鏈接的應(yīng)用程序通常必須在其每個(gè)線程中至少創(chuàng)建一個(gè)自動(dòng)釋放池。 如果應(yīng)用程序使用托管模型(應(yīng)用程序處理對(duì)象的保留和釋放),則自動(dòng)釋放池捕獲從該線程自動(dòng)釋放的任何對(duì)象。

如果應(yīng)用程序使用垃圾收集而不是托管內(nèi)存模型,則不需要?jiǎng)?chuàng)建自動(dòng)釋放池。 垃圾收集應(yīng)用程序中的自動(dòng)釋放池的存在并不是有害的,大多數(shù)情況下都被忽略。 允許代碼模塊必須同時(shí)支持垃圾收集和托管內(nèi)存模式的情況。 在這種情況下,必須存在自動(dòng)釋放池以支持托管內(nèi)存模型代碼,如果應(yīng)用程序運(yùn)行時(shí)啟用了垃圾收集,則會(huì)被忽略。

如果您的應(yīng)用程序使用托管內(nèi)存模型,則創(chuàng)建自動(dòng)釋放池應(yīng)該是您在線程進(jìn)入例程中執(zhí)行的第一件事。 同樣的,摧毀這個(gè)自動(dòng)釋放池應(yīng)該是您在線程中執(zhí)行的最后一件事。 該池確保自動(dòng)釋放的對(duì)象被捕獲,盡管它在線程本身退出之前不會(huì)釋放它們。

 - (void)myThreadMainRoutine 
  { 
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  //頂級(jí)池 
  //線程在線工作 
  [游泳池釋放];  //釋放池中的對(duì)象。 
  } 

因?yàn)轫敿?jí)自動(dòng)釋放池在線程退出之前不會(huì)釋放其對(duì)象,因此長(zhǎng)時(shí)間的線程應(yīng)該創(chuàng)建更多的自動(dòng)釋放池來(lái)更頻繁地釋放對(duì)象。 例如,使用運(yùn)行循環(huán)的線程可能會(huì)每次通過(guò)該運(yùn)行循環(huán)創(chuàng)建和釋放自動(dòng)釋放池。 更頻繁地釋放對(duì)象可以防止應(yīng)用程序的內(nèi)存占用不斷增長(zhǎng),從而導(dǎo)致性能問(wèn)題。 與任何性能相關(guān)的行為一樣,您應(yīng)該衡量代碼的實(shí)際性能,并適當(dāng)調(diào)整您對(duì)自動(dòng)釋放池的使用。

設(shè)置異常處理程序

如果您的應(yīng)用程序捕獲并處理異常,則您的線程代碼應(yīng)準(zhǔn)備好捕獲可能發(fā)生的任何異常。 盡管最好在可能發(fā)生的情況下處理異常,但如果線程中拋出異常,則無(wú)法使您的應(yīng)用程序退出。 在你的線程入口例程中安裝最終的try / catch可以讓你捕獲任何未知的異常并提供適當(dāng)?shù)捻憫?yīng)。

在Xcode中構(gòu)建項(xiàng)目時(shí),可以使用C ++或Objective-C異常處理風(fēng)格。

設(shè)置運(yùn)行循環(huán)

編寫(xiě)代碼時(shí)要在單獨(dú)的線程上運(yùn)行,您有兩個(gè)選項(xiàng)。 第一個(gè)選擇是將一個(gè)線程的代碼寫(xiě)為一個(gè)很長(zhǎng)的任務(wù)要執(zhí)行的很少或沒(méi)有中斷,并在完成線程退出。 第二個(gè)選項(xiàng)是讓你的線程進(jìn)入一個(gè)循環(huán),并讓它們?cè)诘竭_(dá)時(shí)動(dòng)態(tài)處理請(qǐng)求。 第一個(gè)選項(xiàng)不需要您的代碼的特殊設(shè)置; 你只是開(kāi)始做你想做的工作。 但是,第二個(gè)選項(xiàng)涉及設(shè)置線程的運(yùn)行循環(huán)。

OS X和iOS提供內(nèi)置的支持,可在每個(gè)線程中實(shí)現(xiàn)運(yùn)行循環(huán)。 應(yīng)用程序框架自動(dòng)啟動(dòng)應(yīng)用程序主線程的運(yùn)行循環(huán)。 如果創(chuàng)建任何輔助線程,則必須配置運(yùn)行循環(huán)并手動(dòng)啟動(dòng)它。

終止線程

退出線程的推薦方法是讓它正常退出其入口點(diǎn)例程。 雖然Cocoa,POSIX和多處理服務(wù)提供了直接殺死線程的例程,但是強(qiáng)烈建議不要使用此類(lèi)例程。 殺死線程會(huì)阻止線程自身清理。 線程分配的內(nèi)存可能會(huì)泄漏,線程當(dāng)前正在使用的任何其他資源可能無(wú)法正確清除,從而在以后創(chuàng)建潛在問(wèn)題。
如果您期望在操作中終止線程,您應(yīng)該從一開(kāi)始就設(shè)計(jì)線程以響應(yīng)取消或退出消息。 對(duì)于長(zhǎng)時(shí)間運(yùn)行的操作,這可能意味著定期停止工作,并檢查是否有消息到達(dá)。 如果一條消息確實(shí)要求線程退出,線程將有機(jī)會(huì)執(zhí)行任何所需的清理并正常退出; 否則,它可以簡(jiǎn)單地返回工作并處理下一個(gè)數(shù)據(jù)塊。
響應(yīng)取消消息的一種方法是使用運(yùn)行循環(huán)輸入源來(lái)接收這樣的消息。 代碼2-3顯示了該代碼在線程的主入口例程中的外觀結(jié)構(gòu)。 (該示例僅顯示主循環(huán)部分,不包括設(shè)置自動(dòng)釋放池或配置實(shí)際工作的步驟。)示例在運(yùn)行循環(huán)上安裝自定義輸入源,可能會(huì)從另一個(gè)你的線程 有關(guān)設(shè)置輸入源的信息,在執(zhí)行總工作量的一部分后,線程會(huì)短暫運(yùn)行運(yùn)行循環(huán),以查看消息是否到達(dá)輸入源。 如果沒(méi)有,運(yùn)行循環(huán)將立即退出,循環(huán)繼續(xù)下一個(gè)工作塊。 因?yàn)樘幚沓绦虿荒苤苯釉L問(wèn)exitNow
局部變量,所以退出條件通過(guò)線程字典中的鍵值對(duì)來(lái)傳達(dá)。

 - (void)threadMainRoutine 
  { 
  BOOL moreWorkToDo = YES; 
  BOOL exitNow = NO; 
  NSRunLoop * runLoop = [NSRunLoop currentRunLoop]; 
  //將exitNow BOOL添加到線程字典。 
  NSMutableDictionary * threadDict = [[NSThread currentThread] threadDictionary]; 
  [threadDict setValue:[NSNumber numberWithBool:exitNow] forKey:@“ThreadShouldExitNow”]; 
  //安裝輸入源。 
  [self myInstallCustomInputSource]; 
  while(moreWorkToDo &&!exitNow) 
  { 
  //在這里做一大塊工作。 
  //完成后更改moreWorkToDo Boolean的值。 
  //運(yùn)行運(yùn)行循環(huán),如果輸入源不等待觸發(fā)則立即超時(shí)。 
  [runLoop runUntilDate:[NSDate date]]; 
  //檢查輸入源處理程序是否更改了exitNow值。 
  exitNow = [[threadDict valueForKey:@“ThreadShouldExitNow”] boolValue]; 
  } 
  } 
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,196評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事?!?“怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,688評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,654評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,456評(píng)論 6 406
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,955評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,195評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,725評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,608評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,802評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,048評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,422評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,673評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,424評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,762評(píng)論 2 372

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,781評(píng)論 18 139
  • *面試心聲:其實(shí)這些題本人都沒(méi)怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來(lái)就是把...
    Dove_iOS閱讀 27,184評(píng)論 30 470
  • 本文選譯自《Threading Programming Guide》。 導(dǎo)語(yǔ) 線程技術(shù)作為在單個(gè)應(yīng)用程序中并發(fā)執(zhí)行...
    巧巧的二表哥閱讀 2,450評(píng)論 4 24
  • 1.Recordit:GIF錄屏小工具 對(duì)Recordit的具體介紹,可以參考Mac玩法的文章,見(jiàn)下: Recor...
    dibadalu閱讀 4,449評(píng)論 0 6
  • 母親節(jié)前夕,我把新拍的商務(wù)禮儀照片的小樣分享到【爸媽弟妹】群,并提前祝福老媽母親節(jié)快樂(lè)。 老爸老媽、姐姐、弟弟都紛...
    AHa雅涵Ani閱讀 334評(píng)論 0 4