計(jì)算機(jī)那些事(6)——線程

原文鏈接

現(xiàn)代軟件系統(tǒng)中状您,除了進(jìn)程傀蓉,線程也是一個(gè)非常重要的概念欧漱。隨著CPU頻率增長(zhǎng)開(kāi)始出現(xiàn)停滯,處理器逐漸開(kāi)始想多核方向發(fā)展葬燎。多線程误甚,作為實(shí)現(xiàn)軟件并發(fā)執(zhí)行的重要方法之一,也開(kāi)始被重視谱净。

線程基礎(chǔ)

線程概念

線程(Thread)窑邦,也稱輕量級(jí)進(jìn)程(Lightweight Process,LWP)壕探,是程序執(zhí)行流的最小單元冈钦。一個(gè)標(biāo)準(zhǔn)的線程由線程ID、當(dāng)前指令指針(PC)李请、寄存器集合瞧筛、堆棧組成厉熟。通常,一個(gè)進(jìn)程由一個(gè)到多個(gè)線程組成驾窟,各個(gè)線程之間共享程序的內(nèi)存空間(包括代碼段庆猫、數(shù)據(jù)段、堆等)以及一些進(jìn)程級(jí)的資源(如打開(kāi)文件和信號(hào))绅络。

image

同一進(jìn)程中的多個(gè)線程可以互不干擾地并發(fā)執(zhí)行月培,并且共享進(jìn)程的全局變量和堆的數(shù)據(jù)。相對(duì)于單線程進(jìn)程恩急,使用多線程的原因有一下幾點(diǎn):

  • 某個(gè)操作可能會(huì)陷入長(zhǎng)時(shí)間等待杉畜,等待的線程會(huì)進(jìn)入睡眠狀態(tài),無(wú)法繼續(xù)執(zhí)行衷恭。多線程執(zhí)行可以有效利用等待時(shí)間進(jìn)行線程切換此叠。如等待網(wǎng)絡(luò)響應(yīng)。
  • 某個(gè)操作可能會(huì)消耗大量的時(shí)間随珠,如果只有一個(gè)線程灭袁,程序和用戶之間的交互會(huì)被中斷。多線程可以讓一個(gè)線程負(fù)責(zé)交互窗看,另一個(gè)線程負(fù)責(zé)計(jì)算茸歧。
  • 程序本身要求并發(fā)操作,如一個(gè)多端下載軟件(如Bittorrent)显沈。
  • 多CPU或多核處理器软瞎,本身具備同時(shí)執(zhí)行多個(gè)線程的能力,因此單線程程序無(wú)法全面發(fā)揮計(jì)算機(jī)的全部計(jì)算能力拉讯。
  • 相對(duì)于多進(jìn)程應(yīng)用涤浇,多線程在數(shù)據(jù)共享方面效率更高。

線程訪問(wèn)權(quán)限

線程可以訪問(wèn)進(jìn)程內(nèi)存中的所有的數(shù)據(jù)魔慷,包括如下幾個(gè)方面:

  • 全局變量
  • 堆數(shù)據(jù)
  • 函數(shù)里的靜態(tài)變量
  • 程序代碼只锭,任何線程都有權(quán)利讀取并執(zhí)行任何代碼
  • 打開(kāi)的文件,A線程打開(kāi)的文件可以由B線程讀取

當(dāng)然實(shí)際上線程也擁有自己的私有存儲(chǔ)空間院尔,包括如下幾個(gè)方面:

  • :盡管并非完全無(wú)法被其他線程訪問(wèn)纹烹,但是一般情況下還是認(rèn)為棧是私有數(shù)據(jù)。
  • 線程局部存儲(chǔ)(Thread Local Storage召边,TLS):線程局部存儲(chǔ)是某些操作系統(tǒng)為線程單獨(dú)提供的私有空間铺呵,容量有限。
  • 寄存器:寄存器是執(zhí)行流的基本數(shù)據(jù)隧熙,為線程私有片挂。

線程調(diào)度與優(yōu)先級(jí)

當(dāng)線程數(shù)量小于等于處理器數(shù)量時(shí)(并且操作系統(tǒng)支持多處理器),線程的并發(fā)是真正的并發(fā),不同的線程運(yùn)行在不同的處理器上音念。當(dāng)線程數(shù)據(jù)大于處理器數(shù)量時(shí)沪饺,此時(shí)至少有一個(gè)處理器會(huì)運(yùn)行多個(gè)線程。

在單處理器運(yùn)行多線程情況下闷愤,并發(fā)是一種模擬出來(lái)的狀態(tài)整葡。操作系統(tǒng)會(huì)讓這些多線程輪流執(zhí)行,每次僅執(zhí)行一小段時(shí)間(通常是幾十到幾百毫秒)讥脐,這樣每個(gè)線程“看起來(lái)”在同時(shí)執(zhí)行遭居。這樣一個(gè)不斷在處理器上切換不同的線程的行為稱為 線程調(diào)度

在線程調(diào)度中旬渠,線程通常擁有至少三種狀態(tài)俱萍,分別是:

  • 運(yùn)行(Running):此時(shí)線程正在執(zhí)行。
  • 就緒(Ready):此時(shí)線程可以立刻運(yùn)行告丢,但CPI已被占用枪蘑。
  • 等待(Waiting):此時(shí)線程正在等待某一事件(通常是I/O或同步)發(fā)生,無(wú)法執(zhí)行岖免。

處于運(yùn)行中的線程擁有一段可以執(zhí)行的時(shí)間岳颇,這段時(shí)間稱為 時(shí)間片(Time Slice)。當(dāng)時(shí)間片用盡時(shí)颅湘,線程進(jìn)入就緒狀態(tài)话侧。如果線程在時(shí)間片用盡前就開(kāi)始等待某事件,則它將進(jìn)入等待狀態(tài)栅炒。當(dāng)一個(gè)線程離開(kāi)運(yùn)行狀態(tài)時(shí)掂摔,系統(tǒng)會(huì)選擇一個(gè)處于就緒狀態(tài)的線程繼續(xù)執(zhí)行术羔。在一個(gè)處于等待狀態(tài)的線程所等待的事件發(fā)生后赢赊,該線程將進(jìn)入就緒狀態(tài)。如下圖所示為線程的狀態(tài)轉(zhuǎn)移圖级历。

image

在線程調(diào)度中释移,主要有兩種調(diào)度算法:

  • 優(yōu)先級(jí)調(diào)度(Priority Schedule):線程擁有各自的 線程優(yōu)先級(jí)(Thread Priority),高優(yōu)先級(jí)的線程會(huì)更早執(zhí)行寥殖,低優(yōu)先級(jí)的線程需要等待系統(tǒng)中沒(méi)有高優(yōu)先級(jí)的可執(zhí)行線程存在時(shí)才能執(zhí)行玩讳。
  • 輪轉(zhuǎn)調(diào)度(Round Robin Schedule):讓各個(gè)線程輪流執(zhí)行一段時(shí)間片。

實(shí)際應(yīng)用中嚼贡,系統(tǒng)還會(huì)根據(jù)不同線程的表現(xiàn)自動(dòng)調(diào)整優(yōu)先級(jí)熏纯,提高線程調(diào)度效率。在系統(tǒng)中粤策,一般把頻繁等待的線程稱為 IO密集型線程(IO Bound Thread)樟澜;把很少等待的線程稱為 CPU密集型線程(CPU Bound Thread)。通常,IO 密集型線程比 CPU 密集型線程更容易得到優(yōu)先級(jí)的提升秩贰。

在優(yōu)先級(jí)調(diào)度中霹俺,存在一種 餓死(Starvation) 現(xiàn)象,即一個(gè)線程的優(yōu)先級(jí)較低毒费,在它執(zhí)行之前丙唧,總是有較高優(yōu)先級(jí)的線程在它之前執(zhí)行。當(dāng)一個(gè)CPU密集型的線程獲得較高優(yōu)先級(jí)時(shí)觅玻,許多低優(yōu)先級(jí)的進(jìn)程就可能餓死想际。當(dāng)一個(gè)IO密集型的線程獲得較高優(yōu)先級(jí)時(shí),由于大部分之間處于等待狀態(tài)串塑,因此相對(duì)不容易造成其他線程餓死沼琉。為了避免餓死現(xiàn)象,調(diào)度系統(tǒng)通常會(huì)逐步提升那些等待時(shí)間過(guò)長(zhǎng)且未得到執(zhí)行的線程的優(yōu)先級(jí)桩匪。

可搶占線程和不可搶占線程

輪轉(zhuǎn)調(diào)度中打瘪,線程在用盡時(shí)間片后會(huì)被強(qiáng)制剝奪繼續(xù)執(zhí)行的權(quán)利,而進(jìn)入就緒狀態(tài)傻昙,該過(guò)程稱為 搶占(Preemption)闺骚。在早期的一些操作系統(tǒng)中,線程是不可搶占的妆档。在這種調(diào)度模型下僻爽,線程必須主動(dòng)進(jìn)入就緒狀態(tài),而不是靠時(shí)間片用盡來(lái)被強(qiáng)制進(jìn)入贾惦。如果線程始終拒絕進(jìn)入就緒狀態(tài)胸梆,并且不進(jìn)行任何等待操作,其他線程將永遠(yuǎn)無(wú)法執(zhí)行须板。

在不可搶占線程中碰镜,線程會(huì)在兩種情況下主動(dòng)放棄執(zhí)行:

  • 當(dāng)線程試圖等待某些事件時(shí)(如I/O事件)。
  • 線程主動(dòng)放棄時(shí)間片习瑰。

線程安全

多線程程序處于一個(gè)多變的環(huán)境中绪颖,可以訪問(wèn)的全局變量和堆數(shù)據(jù)隨時(shí)都可能被其他的線程改變。因此甜奄,多線程程序在并發(fā)時(shí)數(shù)據(jù)的一致性非常重要柠横。

競(jìng)爭(zhēng)與原子操作

多線程同時(shí)訪問(wèn)一個(gè)共享數(shù)據(jù),可能會(huì)造成嚴(yán)重的后果课兄。以一個(gè)著名的例子為例牍氛,假設(shè)有兩個(gè)線程分別執(zhí)行如下所示的 C 代碼。

// 線程 1
i = 1;
++i;

// 線程 2
--i;

在很多體系結(jié)構(gòu)中烟阐,++i 的實(shí)現(xiàn)方式一般如下:

  1. 讀取 i 到某個(gè)寄存器 X
  2. X++
  3. 將 X 的內(nèi)容存儲(chǔ)至 i

由于線程 1 和線程 2并發(fā)執(zhí)行搬俊,因此兩個(gè)線程的執(zhí)行可能如下(注意,寄存器 X 的 內(nèi)容在不同的線程中是不一樣的,這里用 X[1] 和 X[2] 分別表示線程 1 和線程 2 中的 X)悠抹,如下所示:

執(zhí)行序號(hào) 執(zhí)行指令 語(yǔ)句執(zhí)行后的變量值 線程
1 i = 1 i = 1, X[1] = 未知 1
2 X[1] = i i = 1, X[1] = 1 1
3 X[2] = i i = 1, X[2] = 1 2
4 X[1]++ i = 1, X[1] = 2 1
5 X[2]-- i = 1, X[2] = 0 2
6 i = X[1] i = 2, X[1] = 2 1
7 i = X[2] i = 0, X[2] = 0 2

從程序邏輯上看珠月,兩個(gè)線程都執(zhí)行完畢之后,i 的值應(yīng)該是 1楔敌,但從表中的執(zhí)行序列可以看到啤挎,i 的實(shí)際值是 0。實(shí)際上卵凑,這兩個(gè)線程如果同時(shí)執(zhí)行庆聘,i 的結(jié)果有可能是 0 或 1 或 2。

很明顯勺卢,由于 i++ 操作在多線程環(huán)境下會(huì)出現(xiàn)錯(cuò)誤是因?yàn)樵摬僮鞅痪幾g成匯編代碼后不止一條指令伙判,因此在執(zhí)行時(shí)可能會(huì)被調(diào)度系統(tǒng)打斷,去執(zhí)行別的代碼黑忱。通常宴抚,我們把單指令的操作稱為 原子操作,因?yàn)閱螚l指令的執(zhí)行是不會(huì)被打斷的甫煞。很多體系結(jié)構(gòu)都提供了一些常用的原子指令菇曲,如 i386 就有一條 inc 指令可以直接增加一個(gè)內(nèi)存單元值,可以避免上例的錯(cuò)誤情況抚吠。

盡管原子操作指令非常方便常潮,但是它們僅適用于比較簡(jiǎn)單特定的場(chǎng)合。在復(fù)雜的場(chǎng)合下楷力,比如要保證一個(gè)復(fù)雜的數(shù)據(jù)結(jié)構(gòu)更改的原子性喊式,原子操作指令就力不從心了。這里需要更加通用的手段:鎖萧朝。

同步與鎖

為了避免多個(gè)線程同時(shí)讀寫同一個(gè)數(shù)據(jù)而產(chǎn)生不可預(yù)料的后果岔留,需要將各個(gè)線程對(duì)同一個(gè)數(shù)據(jù)的訪問(wèn)進(jìn)行 同步(Synchronization)。即在一個(gè)線程訪問(wèn)數(shù)據(jù)未結(jié)束時(shí)剪勿,其他線程不得對(duì)同一個(gè)數(shù)據(jù)進(jìn)行訪問(wèn)贸诚。

同步最常見(jiàn)的方法是使用 鎖(Lock)方庭。鎖是一種非強(qiáng)制機(jī)制厕吉,每個(gè)線程在訪問(wèn)數(shù)據(jù)或資源之前首先試圖 獲取(Acquire) 鎖械念,并在訪問(wèn)結(jié)束之后 釋放(Release) 鎖头朱。在鎖已經(jīng)被占用時(shí)試圖獲取鎖時(shí),線程會(huì)等待龄减,直到鎖重新可用项钮。

二元信號(hào)量

二元信號(hào)量(Binary Semaphore) 是最簡(jiǎn)單的一種鎖,只有兩種狀態(tài):占用非占用烁巫。二元信號(hào)量適合只能被唯一一個(gè)線程獨(dú)占訪問(wèn)的資源署隘。當(dāng)二元信號(hào)量處于非占用狀態(tài)時(shí),第一個(gè)試圖獲取該二元信號(hào)量的線程會(huì)獲得該鎖亚隙,并將二元信號(hào)量置為占用狀態(tài)磁餐,此后其他所有試圖獲取該二元信號(hào)量的線程將會(huì)等待,直到該鎖被釋放阿弃。

多元信號(hào)量

多元信號(hào)量是二元信號(hào)量的擴(kuò)展诊霹,簡(jiǎn)稱 信號(hào)量(Semaphore)。一個(gè)初始值為 N 的信號(hào)量允許 N 個(gè)線程并發(fā)訪問(wèn)渣淳。

當(dāng)線程訪問(wèn)資源時(shí)脾还,首先獲取信號(hào)量,進(jìn)行如下操作:

  • 將信號(hào)量減 1入愧。
  • 如果信號(hào)量的值小于 0鄙漏,則進(jìn)入等待狀態(tài),否則繼續(xù)執(zhí)行棺蛛。

當(dāng)線程結(jié)束訪問(wèn)資源后泥张,線程釋放信號(hào)量,進(jìn)行如下操作:

  • 將信號(hào)量的值加 1鞠值。
  • 如果信號(hào)量的值小于 1媚创,喚醒一個(gè)等待中的線程。

互斥量

互斥量(Mutex) 和二元信號(hào)量很相似彤恶,資源僅同時(shí)允許一個(gè)線程訪問(wèn)钞钙,但和信號(hào)量不同的是:信號(hào)量在整個(gè)系統(tǒng)中可以被任意線程獲取并釋放,即同一個(gè)信號(hào)量可以被系統(tǒng)中的一個(gè)線程獲取之后由另一個(gè)線程釋放声离;互斥量則要求哪個(gè)線程獲取了互斥量芒炼,哪個(gè)線程就要負(fù)責(zé)釋放這個(gè)鎖。

臨界區(qū)

臨界區(qū)(Read-Write Lock) 是比互斥量更加嚴(yán)格的同步手段术徊。在術(shù)語(yǔ)中本刽,把臨界區(qū)的鎖的獲取稱為進(jìn)入臨界區(qū),而把鎖的釋放稱為離開(kāi)臨界區(qū)赠涮。臨界區(qū)和互斥量與信號(hào)量的區(qū)別在于:互斥量和信號(hào)量在系統(tǒng)的任何進(jìn)程里都是可見(jiàn)的子寓,即一個(gè)進(jìn)程創(chuàng)建了一個(gè)互斥量或信號(hào)量,另一個(gè)進(jìn)程試圖獲取該鎖是合法的笋除;臨界區(qū)的作用范圍僅限于本進(jìn)程斜友,其他的進(jìn)程無(wú)法獲取該鎖。

讀寫鎖

讀寫鎖(Read-Write Lock) 致力于一種更加特定的場(chǎng)合的同步垃它。對(duì)于一段數(shù)據(jù)鲜屏,多個(gè)線程同時(shí)讀取總是沒(méi)有問(wèn)題的烹看,但假設(shè)操作都不是原子型,只要有任何一個(gè)線程試圖對(duì)該數(shù)據(jù)進(jìn)行修改洛史,就必須使用同步手段來(lái)避免出錯(cuò)惯殊。對(duì)此,可以使用上述的信號(hào)量也殖、互斥量或臨界區(qū)中的任何一種來(lái)進(jìn)行同步靠胜。雖然這樣可以保證程序正確執(zhí)行,但是對(duì)于讀取頻繁的程序毕源,會(huì)顯得非常低效浪漠。讀寫鎖就是用來(lái)提高這種情況下的執(zhí)行效率的。

讀寫鎖有兩種獲取方式:共享的(Shared)霎褐、獨(dú)占的(Exclusive)址愿。當(dāng)鎖處于自由狀態(tài)時(shí),試圖以任何一種方式獲取鎖都能成功冻璃,并將鎖置于對(duì)應(yīng)的狀態(tài)响谓。如果鎖處于共享狀態(tài),其他線程以共享的方式獲取鎖仍然會(huì)成功省艳,此時(shí)這個(gè)鎖分配給了多個(gè)線程娘纷。如果其他線程試圖以獨(dú)占的方式獲取已經(jīng)處于共享狀態(tài)的鎖,那么它必須等待鎖被所有線程釋放跋炕。處于獨(dú)占狀態(tài)的鎖將阻止任何其他線程獲取該鎖赖晶。

條件變量

條件變量(Condition Variable) 作為一種同步手段,作用類似于一個(gè)柵欄辐烂。對(duì)于條件變量遏插,線程可以有兩種操作:首先,線程可以等待條件變量纠修,一個(gè)條件變量可以被多個(gè)線程等待胳嘲。其次,線程可以喚醒條件變量扣草,此時(shí)所有等待此條件變量的線程都會(huì)被喚醒并繼續(xù)執(zhí)行了牛。

線程模型

線程的并發(fā)執(zhí)行是由多處理器或操作系統(tǒng)調(diào)度來(lái)實(shí)現(xiàn)的。但實(shí)際情況要更為復(fù)雜:大多數(shù)操作系統(tǒng)辰妙,包括 Windows 和 Linux鹰祸,都在內(nèi)核里提供線程的支持,內(nèi)核態(tài)線程由多處理器或調(diào)度來(lái)實(shí)現(xiàn)并發(fā)上岗。然而用戶實(shí)際使用的線程并不是內(nèi)核態(tài)線程福荸,而是用戶態(tài)線程蕴坪。用戶態(tài)線程并不一定在操作系統(tǒng)內(nèi)核里對(duì)應(yīng)同等數(shù)量的內(nèi)核態(tài)線程肴掷。它們之間的對(duì)應(yīng)關(guān)系有三種類型敬锐。

一對(duì)一模型

對(duì)于直接支持線程的系統(tǒng),一對(duì)一模型始終是最簡(jiǎn)單的模型呆瞻。對(duì)于一對(duì)一模型台夺,一個(gè)用戶態(tài)線程唯一對(duì)應(yīng)一個(gè)內(nèi)核態(tài)線程,但一個(gè)內(nèi)核態(tài)線程并不一定存在相應(yīng)的用戶態(tài)線程痴脾。模型示意圖如下所示颤介。

image

一對(duì)一模型中,用戶態(tài)線程具有和內(nèi)核態(tài)線程一致的優(yōu)點(diǎn)赞赖,線程之間的并發(fā)是真正的并發(fā)滚朵,一個(gè)線程因?yàn)槟吃蜃枞麜r(shí),其他線程的執(zhí)行不會(huì)受到影響前域。此外辕近,一對(duì)一模型也可以讓多線程程序在多處理器的系統(tǒng)上有更高的效率。

一對(duì)一線程模型也有兩個(gè)缺點(diǎn):

  • 由于許多操作系統(tǒng)限制了內(nèi)核態(tài)線程的數(shù)量匿垄,因此一對(duì)一線程會(huì)讓用戶態(tài)線程的數(shù)量受到限制移宅。
  • 許多操作系統(tǒng)內(nèi)核線程調(diào)度時(shí),上下文切換的開(kāi)銷較大椿疗,導(dǎo)致用戶線程的執(zhí)行效率下降漏峰。

多對(duì)一模型

多對(duì)一模型將多個(gè)用戶態(tài)線程映射到一個(gè)內(nèi)核態(tài)線程上,線程之間的切換由用戶態(tài)的代碼完成届榄。因此相對(duì)于一對(duì)一模型浅乔,多對(duì)一模型的切換要快速許多。模型示意圖如下所示铝条。

image

多對(duì)一模型的問(wèn)題在于:如果其中一個(gè)用戶態(tài)線程阻塞童擎,將導(dǎo)致所有線程都無(wú)法執(zhí)行。另外攻晒,在多處理器系統(tǒng)中顾复,處理器的增多對(duì)于多對(duì)一模型的線程性能也不會(huì)有明顯的提升。多對(duì)一模型的優(yōu)點(diǎn)在于高效的上下文切換和幾乎無(wú)限制的線程數(shù)量鲁捏。

多對(duì)多模型

多對(duì)多模型結(jié)合了多對(duì)一模型和一對(duì)一模型的特點(diǎn)芯砸,將多個(gè)用戶態(tài)線程映射到少數(shù)但不止一個(gè)內(nèi)核態(tài)線程。模型示意圖如下所示给梅。

image

多對(duì)多模型中假丧,一個(gè)用戶態(tài)線程阻塞并不會(huì)導(dǎo)致所有的用戶態(tài)線程阻塞,因?yàn)榇藭r(shí)還有其他的線程可以被調(diào)度來(lái)執(zhí)行动羽。此外包帚,多對(duì)多模型對(duì)用戶線程的數(shù)量也沒(méi)什么限制,在多處理器系統(tǒng)中运吓,多對(duì)多模型的線程也能得到一定的性能提升渴邦,但是提升幅度步入一對(duì)一模型疯趟。

參考

  1. 《程序員的自我修養(yǎng)——鏈接、裝載與庫(kù)》
  2. 《深入理解計(jì)算機(jī)系統(tǒng)》

(完)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谋梭,一起剝皮案震驚了整個(gè)濱河市信峻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓮床,老刑警劉巖盹舞,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異隘庄,居然都是意外死亡踢步,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門丑掺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贾虽,“玉大人,你說(shuō)我怎么就攤上這事吼鱼∨罨恚” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵菇肃,是天一觀的道長(zhǎng)地粪。 經(jīng)常有香客問(wèn)我,道長(zhǎng)琐谤,這世上最難降的妖魔是什么蟆技? 我笑而不...
    開(kāi)封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮斗忌,結(jié)果婚禮上质礼,老公的妹妹穿的比我還像新娘。我一直安慰自己织阳,他們只是感情好眶蕉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著唧躲,像睡著了一般造挽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弄痹,一...
    開(kāi)封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天饭入,我揣著相機(jī)與錄音,去河邊找鬼肛真。 笑死谐丢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播乾忱,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼讥珍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了饭耳?” 一聲冷哼從身側(cè)響起串述,我...
    開(kāi)封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤执解,失蹤者是張志新(化名)和其女友劉穎寞肖,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體衰腌,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡新蟆,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了右蕊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宾濒,靈堂內(nèi)的尸體忽然破棺而出宠进,到底是詐尸還是另有隱情,我是刑警寧澤萝风,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布嘀掸,位于F島的核電站,受9級(jí)特大地震影響规惰,放射性物質(zhì)發(fā)生泄漏睬塌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一歇万、第九天 我趴在偏房一處隱蔽的房頂上張望揩晴。 院中可真熱鬧,春花似錦贪磺、人聲如沸硫兰。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瞄崇。三九已至,卻和暖如春壕曼,著一層夾襖步出監(jiān)牢的瞬間苏研,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工腮郊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摹蘑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓轧飞,卻偏偏與公主長(zhǎng)得像衅鹿,于是被迫代替她去往敵國(guó)和親撒踪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

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

  • 操作系統(tǒng)概論 操作系統(tǒng)的概念 操作系統(tǒng)是指控制和管理計(jì)算機(jī)的軟硬件資源大渤,并合理的組織調(diào)度計(jì)算機(jī)的工作和資源的分配制妄,...
    野狗子嗷嗷嗷閱讀 11,936評(píng)論 3 34
  • 我的2017, 過(guò)的還可以,走走停停泵三,找到目的地耕捞,對(duì)的人還沒(méi)在一起,說(shuō)過(guò)的話還是會(huì)忘記烫幕,一年就這樣離去俺抽。 我的2...
    包曉閱讀 141評(píng)論 0 0
  • 今天是第二天到公司上班。 早上下了一陣雨较曼,不想騎車磷斧,昨天收拾屋子,鼻炎犯了捷犹,所以不想吹風(fēng)弛饭。算好了時(shí)間打滴滴到公司,...
    大叔寶貝閱讀 220評(píng)論 0 1
  • 圖片發(fā)自簡(jiǎn)書App 一 前段時(shí)間,我一閨蜜翠桦,帶我去一家新開(kāi)的理發(fā)店剪頭發(fā)横蜒。下決心剪發(fā),是因?yàn)樗囊痪湓挘耗阒绬幔?..
    無(wú)公害的菜菜閱讀 17,474評(píng)論 20 15
  • 文:而立虛云 我聽(tīng)說(shuō)销凑,人類的實(shí)際壽命應(yīng)該只有39歲丛晌,這個(gè)數(shù)字是通過(guò)計(jì)算哺乳動(dòng)物的發(fā)育期和性成熟期的時(shí)間比例算出來(lái)的...
    通靈半藏閱讀 301評(píng)論 0 1