Linux - 進(jìn)程赁豆、線程仅醇、上下文切換

進(jìn)程定義

進(jìn)程是正在運(yùn)行的程序的實(shí)例,是資源擁有的基本單位魔种。

進(jìn)程狀態(tài)

當(dāng)一個進(jìn)程開始運(yùn)行時(shí)析二,它可能會經(jīng)歷下面這幾種狀態(tài)



圖中會涉及三種狀態(tài)

  • 運(yùn)行態(tài),運(yùn)行態(tài)指的就是進(jìn)程實(shí)際占用 CPU 時(shí)間片運(yùn)行時(shí)
  • 就緒態(tài)务嫡,就緒態(tài)指的是可運(yùn)行甲抖,但因?yàn)槠渌M(jìn)程正在運(yùn)行而處于就緒狀態(tài)
  • 阻塞態(tài),除非某種外部事件發(fā)生心铃,否則進(jìn)程不能運(yùn)行

邏輯上來說准谚,運(yùn)行態(tài)和就緒態(tài)是很相似的。這兩種情況下都表示進(jìn)程可運(yùn)行去扣,但是第二種情況沒有獲得 CPU 時(shí)間分片柱衔。第三種狀態(tài)與前兩種狀態(tài)不同的原因是這個進(jìn)程不能運(yùn)行,CPU 空閑時(shí)也不能運(yùn)行愉棱。

三種狀態(tài)會涉及四種狀態(tài)間的切換唆铐,在操作系統(tǒng)發(fā)現(xiàn)進(jìn)程不能繼續(xù)執(zhí)行時(shí)會發(fā)生狀態(tài) 1的輪轉(zhuǎn),在某些系統(tǒng)中進(jìn)程執(zhí)行系統(tǒng)調(diào)用奔滑,例如 pause艾岂,來獲取一個阻塞的狀態(tài)。在其他系統(tǒng)中包括 UNIX朋其,當(dāng)進(jìn)程從管道或特殊文件(例如終端)中讀取沒有可用的輸入時(shí)王浴,該進(jìn)程會被自動終止脆炎。

轉(zhuǎn)換 2 和轉(zhuǎn)換 3 都是由進(jìn)程調(diào)度程序(操作系統(tǒng)的一部分)引起的,進(jìn)程本身不知道調(diào)度程序的存在氓辣。轉(zhuǎn)換 2 的出現(xiàn)說明進(jìn)程調(diào)度器認(rèn)定當(dāng)前進(jìn)程已經(jīng)運(yùn)行了足夠長的時(shí)間秒裕,是時(shí)候讓其他進(jìn)程運(yùn)行 CPU 時(shí)間片了。當(dāng)所有其他進(jìn)程都運(yùn)行過后钞啸,這時(shí)候該是讓第一個進(jìn)程重新獲得 CPU 時(shí)間片的時(shí)候了几蜻,就會發(fā)生轉(zhuǎn)換 3。

程序調(diào)度指的是体斩,決定哪個進(jìn)程優(yōu)先被運(yùn)行和運(yùn)行多久梭稚,這是很重要的一點(diǎn)。已經(jīng)設(shè)計(jì)出許多算法來嘗試平衡系統(tǒng)整體效率與各個流程之間的競爭需求硕勿。

當(dāng)進(jìn)程等待的一個外部事件發(fā)生時(shí)(如從外部輸入一些數(shù)據(jù)后)哨毁,則發(fā)生轉(zhuǎn)換 4。如果此時(shí)沒有其他進(jìn)程在運(yùn)行源武,則立刻觸發(fā)轉(zhuǎn)換 3,該進(jìn)程便開始運(yùn)行想幻,否則該進(jìn)程會處于就緒階段粱栖,等待 CPU 空閑后再輪到它運(yùn)行。

進(jìn)程控制結(jié)構(gòu)

在操作系統(tǒng)中脏毯,是用進(jìn)程控制塊(process control block闹究,PCB)數(shù)據(jù)結(jié)構(gòu)來描述進(jìn)程的,
Linux中的PCB是task_struct結(jié)構(gòu)體食店。


包含

  • 進(jìn)程狀態(tài)渣淤;
  • 全局變量;
  • 虛擬地址空間的信息吉嫩;
  • 所打開文件的列表价认;
  • 所使用的 I/O 設(shè)備信息。

Linux內(nèi)核其實(shí)是不區(qū)分進(jìn)程和線程的自娩,調(diào)度器實(shí)際是識別task_struct進(jìn)行調(diào)度用踩。
無論進(jìn)程線程,底層都對應(yīng)一個task_struct忙迁,進(jìn)程和線程的區(qū)別是共享資源的多少脐彩,兩個進(jìn)程間完全不共享資源,兩個線程間共享所有資源姊扔。

PCB組織方式(進(jìn)程表)

通常是通過鏈表的方式進(jìn)行組織惠奸,把具有相同狀態(tài)的進(jìn)程鏈在一起,組成各種隊(duì)列恰梢。比如:

將所有處于就緒狀態(tài)的進(jìn)程鏈在一起佛南,稱為就緒隊(duì)列梗掰;
把所有因等待某事件而處于等待狀態(tài)的進(jìn)程鏈在一起就組成各種阻塞隊(duì)列;

另外共虑,對于運(yùn)行隊(duì)列在單核 CPU 系統(tǒng)中則只有一個運(yùn)行指針了愧怜,因?yàn)閱魏?CPU 在某個時(shí)間,只能運(yùn)行一個程序妈拌。

那么拥坛,就緒隊(duì)列和阻塞隊(duì)列鏈表的組織形式如下圖:


進(jìn)程間通信方式

  • 消息傳遞:消息傳遞是進(jìn)程間實(shí)現(xiàn)通信和同步等待的機(jī)制,使用消息傳遞尘分,進(jìn)程間的交流不需要共享變量猜惋,直接就可以進(jìn)行通信;消息傳遞分為發(fā)送方和接收方

  • 先進(jìn)先出隊(duì)列:先進(jìn)先出隊(duì)列指的是兩個不相關(guān)聯(lián)進(jìn)程間的通信培愁,兩個進(jìn)程之間可以彼此相互進(jìn)程通信著摔,這是一種全雙工通信方式

  • 管道:管道用于兩個相關(guān)進(jìn)程之間的通信,這是一種半雙工的通信方式定续,如果需要全雙工谍咆,需要另外一個管道。

  • 直接通信:在這種進(jìn)程通信的方式中私股,進(jìn)程與進(jìn)程之間只存在一條鏈接摹察,進(jìn)程間要明確通信雙方的命名。

  • 間接通信:間接通信是通信雙方不會直接建立連接倡鲸,而是找到一個中介者供嚎,這個中介者可能是個對象等等,進(jìn)程可以在其中放置消息峭状,并且可以從中刪除消息克滴,以此達(dá)到進(jìn)程間通信的目的。

  • 消息隊(duì)列:消息隊(duì)列是內(nèi)核中存儲消息的鏈表优床,它由消息隊(duì)列標(biāo)識符進(jìn)行標(biāo)識劝赔,這種方式能夠在不同的進(jìn)程之間提供全雙工的通信連接。

  • 共享內(nèi)存:共享內(nèi)存是使用所有進(jìn)程之間的內(nèi)存來建立連接羔巢,這種類型需要同步進(jìn)程訪問來相互保護(hù)望忆。

CPU上下文與切換

在每個任務(wù)運(yùn)行前,CPU 都需要知道任務(wù)從哪里加載竿秆、又從哪里開始運(yùn)行启摄,也就是說,需要系統(tǒng)事先幫它設(shè)置好 CPU 寄存器和程序計(jì)數(shù)器(Program Counter幽钢,PC)歉备。
CPU 寄存器,是 CPU 內(nèi)置的容量小匪燕、但速度極快的內(nèi)存蕾羊。而程序計(jì)數(shù)器喧笔,則是用來存儲 CPU 正在執(zhí)行的指令位置、或者即將執(zhí)行的下一條指令位置龟再。它們都是 CPU 在運(yùn)行任何任務(wù)前茶没,必須的依賴環(huán)境瞒窒,因此也被叫做 CPU 上下文姥敛。

CPU 上下文切換砂沛,就是先把前一個任務(wù)的 CPU 上下文(也就是 CPU 寄存器和程序計(jì)數(shù)器)保存起來,然后加載新任務(wù)的上下文到這些寄存器和程序計(jì)數(shù)器哀澈,最后再跳轉(zhuǎn)到程序計(jì)數(shù)器所指的新位置牌借,運(yùn)行新任務(wù)。而這些保存下來的上下文割按,會存儲在系統(tǒng)內(nèi)核中膨报,并在任務(wù)重新調(diào)度執(zhí)行時(shí)再次加載進(jìn)來。

進(jìn)程上下文切換

Linux 按照特權(quán)等級适荣,把進(jìn)程的運(yùn)行空間分為內(nèi)核空間和用戶空間现柠,分別對應(yīng)著下圖中, CPU 特權(quán)等級的 Ring 0 和 Ring 3弛矛。內(nèi)核空間(Ring 0)具有最高權(quán)限晒旅,可以直接訪問所有資源;用戶空間(Ring 3)只能訪問受限資源汪诉,不能直接訪問內(nèi)存等硬件設(shè)備,必須通過系統(tǒng)調(diào)用陷入到內(nèi)核中谈秫,才能訪問這些特權(quán)資源扒寄。



進(jìn)程既可以在用戶空間運(yùn)行,又可以在內(nèi)核空間中運(yùn)行拟烫。
進(jìn)程在用戶空間運(yùn)行時(shí)该编,被稱為進(jìn)程的用戶態(tài),而陷入內(nèi)核空間的時(shí)候硕淑,被稱為進(jìn)程的內(nèi)核態(tài)课竣。

系統(tǒng)調(diào)用

從用戶態(tài)到內(nèi)核態(tài)的轉(zhuǎn)變,需要通過系統(tǒng)調(diào)用來完成置媳。比如于樟,當(dāng)我們查看文件內(nèi)容時(shí),就需要多次系統(tǒng)調(diào)用來完成:首先調(diào)用 open() 打開文件拇囊,然后調(diào)用 read() 讀取文件內(nèi)容迂曲,并調(diào)用 write() 將內(nèi)容寫到標(biāo)準(zhǔn)輸出,最后再調(diào)用 close() 關(guān)閉文件寥袭。

在這個過程中就發(fā)生了 CPU 上下文切換路捧,整個過程是這樣的:
1关霸、保存 CPU 寄存器里原來用戶態(tài)的指令位
2、為了執(zhí)行內(nèi)核態(tài)代碼杰扫,CPU 寄存器需要更新為內(nèi)核態(tài)指令的新位置队寇。
3、跳轉(zhuǎn)到內(nèi)核態(tài)運(yùn)行內(nèi)核任務(wù)章姓。
4佳遣、當(dāng)系統(tǒng)調(diào)用結(jié)束后,CPU 寄存器需要恢復(fù)原來保存的用戶態(tài)啤覆,然后再切換到用戶空間苍日,繼續(xù)運(yùn)行進(jìn)程。

所以窗声,一次系統(tǒng)調(diào)用的過程相恃,其實(shí)是發(fā)生了兩次 CPU 上下文切換。(用戶態(tài)-內(nèi)核態(tài)-用戶態(tài))

不過笨觅,需要注意的是拦耐,系統(tǒng)調(diào)用過程中,并不會涉及到虛擬內(nèi)存等進(jìn)程用戶態(tài)的資源见剩,也不會切換進(jìn)程杀糯。這跟我們通常所說的進(jìn)程上下文切換是不一樣的:進(jìn)程上下文切換,是指從一個進(jìn)程切換到另一個進(jìn)程運(yùn)行苍苞;而系統(tǒng)調(diào)用過程中一直是同一個進(jìn)程在運(yùn)行固翰。

所以,系統(tǒng)調(diào)用過程通常稱為特權(quán)模式切換羹呵,而不是上下文切換骂际。系統(tǒng)調(diào)用屬于同進(jìn)程內(nèi)的 CPU 上下文切換。但實(shí)際上冈欢,系統(tǒng)調(diào)用過程中歉铝,CPU 的上下文切換還是無法避免的。

進(jìn)程上下文切換跟系統(tǒng)調(diào)用區(qū)別

首先凑耻,進(jìn)程是由內(nèi)核來管理和調(diào)度的太示,進(jìn)程的切換只能發(fā)生在內(nèi)核態(tài)。所以香浩,進(jìn)程的上下文不僅包括了虛擬內(nèi)存类缤、棧、全局變量等用戶空間的資源弃衍,還包括了內(nèi)核堆棧呀非、寄存器等內(nèi)核空間的狀態(tài)。

因此,進(jìn)程的上下文切換就比系統(tǒng)調(diào)用時(shí)多了一步:在保存內(nèi)核態(tài)資源(當(dāng)前進(jìn)程的內(nèi)核狀態(tài)和 CPU 寄存器)之前岸裙,需要先把該進(jìn)程的用戶態(tài)資源(虛擬內(nèi)存猖败、棧等)保存下來;而加載了下一進(jìn)程的內(nèi)核態(tài)后降允,還需要刷新進(jìn)程的虛擬內(nèi)存和用戶棧恩闻。

如下圖所示,保存上下文和恢復(fù)上下文的過程并不是“免費(fèi)”的剧董,需要內(nèi)核在 CPU 上運(yùn)行才能完成幢尚。


進(jìn)程上下文切換潛在的性能問題

根據(jù) Tsuna 的測試報(bào)告,每次上下文切換都需要幾十納秒到數(shù)微秒的 CPU 時(shí)間翅楼。這個時(shí)間還是相當(dāng)可觀的尉剩,特別是在進(jìn)程上下文切換次數(shù)較多的情況下,很容易導(dǎo)致 CPU 將大量時(shí)間耗費(fèi)在寄存器毅臊、內(nèi)核棧以及虛擬內(nèi)存等資源的保存和恢復(fù)上理茎,進(jìn)而大大縮短了真正運(yùn)行進(jìn)程的時(shí)間。這也正是導(dǎo)致平均負(fù)載升高的一個重要因素管嬉。

另外皂林,Linux 通過 TLB(Translation Lookaside Buffer)來管理虛擬內(nèi)存到物理內(nèi)存的映射關(guān)系。當(dāng)虛擬內(nèi)存更新后蚯撩,TLB 也需要刷新础倍,內(nèi)存的訪問也會隨之變慢。特別是在多處理器系統(tǒng)上胎挎,緩存是被多個處理器共享的沟启,刷新緩存不僅會影響當(dāng)前處理器的進(jìn)程,還會影響共享緩存的其他處理器的進(jìn)程犹菇。

發(fā)生上下文切換場景
  1. 為了保證所有進(jìn)程可以得到公平調(diào)度美浦,CPU 時(shí)間被劃分為一段段的時(shí)間片,這些時(shí)間片再被輪流分配給各個進(jìn)程项栏。這樣,當(dāng)某個進(jìn)程的時(shí)間片耗盡了蹬竖,就會被系統(tǒng)掛起沼沈,切換到其它正在等待 CPU 的進(jìn)程運(yùn)行。
  2. 進(jìn)程在系統(tǒng)資源不足(比如內(nèi)存不足)時(shí)币厕,要等到資源滿足后才可以運(yùn)行列另,這個時(shí)候進(jìn)程也會被掛起,并由系統(tǒng)調(diào)度其他進(jìn)程運(yùn)行旦装。
  3. 當(dāng)進(jìn)程通過睡眠函數(shù) sleep 這樣的方法將自己主動掛起時(shí)页衙,自然也會重新調(diào)度。
  4. 當(dāng)有優(yōu)先級更高的進(jìn)程運(yùn)行時(shí),為了保證高優(yōu)先級進(jìn)程的運(yùn)行店乐,當(dāng)前進(jìn)程會被掛起艰躺,由高優(yōu)先級進(jìn)程來運(yùn)行
  5. 發(fā)生硬件中斷時(shí),CPU 上的進(jìn)程會被中斷掛起眨八,轉(zhuǎn)而執(zhí)行內(nèi)核中的中斷服務(wù)程序腺兴。

線程

線程是調(diào)度的基本單位,是進(jìn)程當(dāng)中的一條執(zhí)行流程廉侧。
同一個進(jìn)程內(nèi)多個線程之間可以共享代碼段页响、數(shù)據(jù)段、打開的文件等資源段誊,但每個線程都有獨(dú)立一套的寄存器和棧闰蚕,這樣可以確保線程的控制流是相對獨(dú)立的。

線程上下文切換

內(nèi)核中的任務(wù)調(diào)度连舍,實(shí)際上的調(diào)度對象是線程没陡;而進(jìn)程只是給線程提供了虛擬內(nèi)存、全局變量等資源烟瞧。

所以诗鸭,對于線程和進(jìn)程,我們可以這么理解:

  • 當(dāng)進(jìn)程只有一個線程時(shí)参滴,可以認(rèn)為進(jìn)程就等于線程强岸。
  • 當(dāng)進(jìn)程擁有多個線程時(shí),這些線程會共享相同的虛擬內(nèi)存和全局變量等資源砾赔。這些資源在上下文切換時(shí)是不需要修改的蝌箍。
  • 另外,線程也有自己的私有數(shù)據(jù)暴心,比如棧和寄存器等妓盲,這些在上下文切換時(shí)也是需要保存的。

這么一來专普,線程的上下文切換其實(shí)就可以分為兩種情況:

  • 第一種悯衬, 前后兩個線程屬于不同進(jìn)程。此時(shí)檀夹,因?yàn)橘Y源不共享筋粗,所以切換過程就跟進(jìn)程上下文切換是一樣。
  • 第二種炸渡,前后兩個線程屬于同一個進(jìn)程娜亿。此時(shí),因?yàn)樘摂M內(nèi)存是共享的蚌堵,所以在切換時(shí)买决,虛擬內(nèi)存這些資源就保持不動沛婴,只需要切換線程的私有數(shù)據(jù)、寄存器等不共享的數(shù)據(jù)督赤。

雖然同為上下文切換嘁灯,但同進(jìn)程內(nèi)的線程切換,要比多進(jìn)程間的切換消耗更少的資源够挂,而這旁仿,也正是多線程代替多進(jìn)程的一個優(yōu)勢。

線程與進(jìn)程比較

從概念來說孽糖,線程是調(diào)度的基本單位枯冈,而進(jìn)程則是資源擁有的基本單位。
從本質(zhì)上來說办悟,線程與進(jìn)程的實(shí)現(xiàn)方式是一樣的尘奏,底層都是由一個叫task_struct的結(jié)構(gòu)體實(shí)現(xiàn),可以被cpu調(diào)度病蛉,只是資源共享方式不同炫加,進(jìn)程間是不共享資源,而同一個進(jìn)程內(nèi)的線程共享這個進(jìn)程的所有資源铺然。

線程的實(shí)現(xiàn)

  • 用戶線程(User Thread):在用戶空間實(shí)現(xiàn)的線程俗孝,不是由內(nèi)核管理的線程,是由用戶態(tài)的線程庫來完成線程的管理魄健,例如go的goroutine赋铝;
  • 內(nèi)核線程(Kernel Thread):在內(nèi)核中實(shí)現(xiàn)的線程,是由內(nèi)核管理的線程沽瘦;
  • 輕量級進(jìn)程(LightWeight Process):在內(nèi)核中來支持用戶線程革骨;例如Linux的pthread_create。
用戶線程

用戶線程是基于用戶態(tài)的線程管理庫來實(shí)現(xiàn)的析恋,那么線程控制塊(Thread Control Block, TCB) 也是在庫里面來實(shí)現(xiàn)的良哲,對于操作系統(tǒng)而言是看不到這個 TCB 的,它只能看到整個進(jìn)程的 PCB助隧。

所以筑凫,用戶線程的整個線程管理和調(diào)度,操作系統(tǒng)是不直接參與的并村,而是由用戶級線程庫函數(shù)來完成線程的管理漏健,包括線程的創(chuàng)建、終止橘霎、同步和調(diào)度等。


用戶線程的優(yōu)點(diǎn):

  • 每個進(jìn)程都需要有它私有的線程控制塊(TCB)列表殖属,用來跟蹤記錄它各個線程狀態(tài)信息(PC姐叁、棧指針、寄存器),TCB 由用戶級線程庫函數(shù)來維護(hù)外潜,可用于不支持線程技術(shù)的操作系統(tǒng)原环;
  • 用戶線程的切換也是由線程庫函數(shù)來完成的,無需用戶態(tài)與內(nèi)核態(tài)的切換处窥,所以速度特別快嘱吗;

用戶線程的缺點(diǎn):

  • 由于操作系統(tǒng)不參與線程的調(diào)度,如果一個線程發(fā)起了系統(tǒng)調(diào)用而阻塞滔驾,那進(jìn)程所包含的用戶線程都不能執(zhí)行了谒麦。
  • 當(dāng)一個線程開始運(yùn)行后,除非它主動地交出 CPU 的使用權(quán)哆致,否則它所在的進(jìn)程當(dāng)中的其他線程無法運(yùn)行绕德,因?yàn)橛脩魬B(tài)的線程沒法打斷當(dāng)前運(yùn)行中的線程,它沒有這個特權(quán)摊阀,只有操作系統(tǒng)才有耻蛇,但是用戶線程不是由操作系統(tǒng)管理的。
  • 由于時(shí)間片分配給進(jìn)程(或者輕量級進(jìn)程)胞此,故與其他進(jìn)程比臣咖,在多線程執(zhí)行時(shí),每個線程得到的時(shí)間片較少漱牵,執(zhí)行會比較慢夺蛇;
內(nèi)核線程

內(nèi)核線程是由操作系統(tǒng)管理的,線程對應(yīng)的 TCB 自然是放在操作系統(tǒng)里的布疙,這樣線程的創(chuàng)建蚊惯、終止和管理都是由操作系統(tǒng)負(fù)責(zé)。

內(nèi)核線程的優(yōu)點(diǎn):

  • 在一個進(jìn)程當(dāng)中灵临,如果某個內(nèi)核線程發(fā)起系統(tǒng)調(diào)用而被阻塞截型,并不會影響其他內(nèi)核線程的運(yùn)行;
  • 分配給線程儒溉,多線程的進(jìn)程獲得更多的 CPU 運(yùn)行時(shí)間宦焦;

內(nèi)核線程的缺點(diǎn):

  • 在支持內(nèi)核線程的操作系統(tǒng)中,由內(nèi)核來維護(hù)進(jìn)程和線程的上下文信息顿涣,如 PCB 和 TCB波闹;
  • 線程的創(chuàng)建、終止和切換都是通過系統(tǒng)調(diào)用的方式來進(jìn)行涛碑,因此對于系統(tǒng)來說精堕,系統(tǒng)開銷比較大;
輕量級進(jìn)程

是內(nèi)核支持的用戶線程蒲障,一個進(jìn)程可有一個或多個 LWP歹篓,每個 LWP 是跟內(nèi)核線程一對一映射的瘫证,也就是 LWP 都是由一個內(nèi)核線程支持。

另外庄撮,LWP 只能由內(nèi)核管理并像普通進(jìn)程一樣被調(diào)度背捌,Linux 內(nèi)核是支持 LWP 的典型例子。

在大多數(shù)系統(tǒng)中洞斯,LWP與普通進(jìn)程的區(qū)別也在于它只有一個最小的執(zhí)行上下文和調(diào)度程序所需的統(tǒng)計(jì)信息毡庆。一般來說,一個進(jìn)程代表程序的一個實(shí)例烙如,而 LWP 代表程序的執(zhí)行線程么抗,因?yàn)橐粋€執(zhí)行線程不像進(jìn)程那樣需要那么多狀態(tài)信息,所以 LWP 也不帶有這樣的信息厅翔。

在 LWP 之上也是可以使用用戶線程的乖坠,那么 LWP 與用戶線程的對應(yīng)關(guān)系就有三種:

1 : 1,即一個 LWP 對應(yīng) 一個用戶線程刀闷;
N : 1熊泵,即一個 LWP 對應(yīng)多個用戶線程;
N : N甸昏,即多個 LMP 對應(yīng)多個用戶線程顽分;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市施蜜,隨后出現(xiàn)的幾起案子卒蘸,更是在濱河造成了極大的恐慌,老刑警劉巖翻默,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缸沃,死亡現(xiàn)場離奇詭異,居然都是意外死亡修械,警方通過查閱死者的電腦和手機(jī)趾牧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肯污,“玉大人翘单,你說我怎么就攤上這事”脑” “怎么了哄芜?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長柬唯。 經(jīng)常有香客問我认臊,道長,這世上最難降的妖魔是什么锄奢? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任失晴,我火速辦了婚禮冤议,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘师坎。我一直安慰自己,他們只是感情好堪滨,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布胯陋。 她就那樣靜靜地躺著,像睡著了一般袱箱。 火紅的嫁衣襯著肌膚如雪遏乔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天发笔,我揣著相機(jī)與錄音盟萨,去河邊找鬼。 笑死了讨,一個胖子當(dāng)著我的面吹牛捻激,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播前计,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼胞谭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了男杈?” 一聲冷哼從身側(cè)響起丈屹,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伶棒,沒想到半個月后旺垒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肤无,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年先蒋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舅锄。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡鞭达,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出皇忿,到底是詐尸還是另有隱情畴蹭,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布鳍烁,位于F島的核電站叨襟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏幔荒。R本人自食惡果不足惜糊闽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一梳玫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧右犹,春花似錦提澎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掂墓,卻和暖如春谦纱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背君编。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工跨嘉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吃嘿。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓祠乃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唠椭。 傳聞我的和親對象是個殘疾皇子跳纳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

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