FreeRTOS學(xué)習(xí)筆記(5)——互斥量

一、頭文件

#include "FreeRTOS.h"
#include "semphr.h"

二眷细、互斥量

2.1 基本概念

互斥量又稱互斥信號量(本質(zhì)是信號量),是一種特殊的二值信號量礼搁,它和信號量不同的是宙搬,它支持互斥量所有權(quán)笨腥、遞歸訪問以及防止優(yōu)先級翻轉(zhuǎn)的特性,用于實現(xiàn)對臨界資源的獨占式處理勇垛。任意時刻互斥量的狀態(tài)只有兩種脖母,開鎖或閉鎖。當(dāng)互斥量被任務(wù)持有時闲孤,該互斥量處于閉鎖狀態(tài)谆级,這個任務(wù)獲得互斥量的所有權(quán)。當(dāng)該任務(wù)釋放這個互斥量時讼积,該互斥量處于開鎖狀態(tài)肥照,任務(wù)失去該互斥量的所有權(quán)。當(dāng)一個任務(wù)持有互斥量時勤众,其他任務(wù)將不能再對該互斥量進行開鎖或持有建峭。持有該互斥量的任務(wù)也能夠再次獲得這個鎖而不被掛起,這就是遞歸訪問决摧,也就是遞歸互斥量的特性亿蒸,這個特性與一般的信號量有很大的不同,在信號量中掌桩,由于已經(jīng)不存在可用的信號量边锁,任務(wù)遞歸獲取信號量時會發(fā)生主動掛起任務(wù)最終形成死鎖。

如果想要用于實現(xiàn)同步(任務(wù)之間或者任務(wù)與中斷之間)波岛,二值信號量或許是更好的選擇茅坛,雖然互斥量也可以用于任務(wù)與任務(wù)、任務(wù)與中斷的同步,但是互斥量更多的是用于保護資源的互鎖贡蓖。

用于互鎖的互斥量可以充當(dāng)保護資源的令牌曹鸠,當(dāng)一個任務(wù)希望訪問某個資源時,它必須先獲取令牌斥铺。當(dāng)任務(wù)使用完資源后彻桃,必須還回令牌,以便其它任務(wù)可以訪問該資源晾蜘。是不是很熟悉邻眷,在我們的二值信號量里面也是一樣的,用于保護臨界資源剔交,保證多任務(wù)的訪問井然有序肆饶。當(dāng)任務(wù)獲取到信號量的時候才能開始使用被保護的資源,使用完就釋放信號量岖常,下一個任務(wù)才能獲取到信號量從而可用使用被保護的資源驯镊。但是信號量會導(dǎo)致的另一個潛在問題,那就是任務(wù)優(yōu)先級翻轉(zhuǎn)竭鞍。而 FreeRTOS 提供的互斥量可以通過優(yōu)先級繼承算法阿宅,可以降低優(yōu)先級翻轉(zhuǎn)問題產(chǎn)生的影響,所以笼蛛,用于臨界資源的保護一般建議使用互斥量洒放。

2.2 運作機制


用互斥量處理不同任務(wù)對臨界資源的同步訪問時,任務(wù)想要獲得互斥量才能進行資源訪問滨砍,如果一旦有任務(wù)成功獲得了互斥量往湿,則互斥量立即變?yōu)殚]鎖狀態(tài),此時其他任務(wù)會因為獲取不到互斥量而不能訪問這個資源惋戏,任務(wù)會根據(jù)用戶自定義的等待時間進行等待领追,直到互斥量被持有的任務(wù)釋放后,其他任務(wù)才能獲取互斥量從而得以訪問該臨界資源响逢,此時互斥量再次上鎖绒窑,如此一來就可以確保每個時刻只有一個任務(wù)正在訪問這個臨界資源,保證了臨界資源操作的安全性舔亭。

2.3 互斥量與遞歸互斥量

  • 互斥量更適合于可能會引起優(yōu)先級翻轉(zhuǎn)的情況些膨。
  • 遞歸互斥量更適用于任務(wù)可能會多次獲取互斥量的情況下。這樣可以避免同一任務(wù)多次遞歸持有而造成死鎖的問題钦铺。

三订雾、相關(guān)API說明

3.1 xSemaphoreCreateMutex

用于創(chuàng)建一個互斥量,并返回一個互斥量句柄矛洞。

函數(shù) #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX )
參數(shù)
返回值 互斥量句柄

要想使用該函數(shù)必須在 FreeRTOSConfig.h 中把 configSUPPORT_DYNAMIC_ALLOCATION 定義為 1 來使能洼哎。


同時必須在 FreeRTOSConfig.h 中把 configUSE_MUTEXES 定義為 1 來使能。

3.2 xSemaphoreCreateRecursiveMutex

用于創(chuàng)建一個遞歸互斥量,不是遞歸的互斥量由函數(shù) xSemaphoreCreateMutex() 或 xSemaphoreCreateMutexStatic()創(chuàng)建噩峦,且只能被同一個任務(wù)獲取一次锭沟,如果同一個任務(wù)想再次獲取則會失敗。遞歸信號量則相反识补,它可以被同一個任務(wù)獲取很多次族淮,獲取多少次就需要釋放多少次。遞歸信號量與互斥量一樣李请,都實現(xiàn)了優(yōu)先級繼承機制,可以減少優(yōu)先級反轉(zhuǎn)的反生厉熟。

函數(shù) #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX )
參數(shù)
返回值 遞歸互斥量句柄

要想使用該函數(shù)必須在 FreeRTOSConfig.h 中把 configSUPPORT_DYNAMIC_ALLOCATION 定義為 1 來使能导盅。


同時必須在 FreeRTOSConfig.h 中把 configUSE_RECURSIVE_MUTEXES 定義為 1 來使能。

3.3 vSemaphoreDelete

用于刪除一個信號量揍瑟,包括二值信號量白翻,計數(shù)信號量,互斥量和遞歸互斥量绢片。如果有任務(wù)阻塞在該信號量上滤馍,那么不要刪除該信號量。

函數(shù) void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )
參數(shù) xSemaphore: 信號量句柄
返回值

3.4 xSemaphoreTake

用于獲取信號量底循,不帶中斷保護巢株。獲取的信號量對象可以是二值信號量、計數(shù)信號量和互斥量熙涤,但是遞歸互斥量并不能使用這個 API 函數(shù)獲取阁苞。

函數(shù) xSemaphoreTake( SemaphoreHandle_t xSemaphore, TickType_t xBlockTime )
參數(shù) xSemaphore: 信號量句柄
xBlockTime: 等待信號量可用的最大超時時間,單位為 tick(即系統(tǒng)節(jié)拍周期)祠挫。如果宏 INCLUDE_vTaskSuspend 定義為 1 且形參 xTicksToWait 設(shè)置為 portMAX_DELAY 那槽,則任務(wù)將一直阻塞在該信號量上(即沒有超時時間)
返回值 成功返回 pdTRUE,否則返回 errQUEUE_EMPTY

3.5 xSemaphoreTakeRecursive

用于獲取遞歸互斥量的宏等舔,與互斥量的獲取函數(shù)一樣骚灸,xSemaphoreTakeRecursive()也是一個宏定義,它最終使用現(xiàn)有的隊列機制慌植,實際執(zhí)行的函數(shù)是 xQueueTakeMutexRecursive() 甚牲。 獲取遞歸互斥量之前必須由 xSemaphoreCreateRecursiveMutex() 這個函數(shù)創(chuàng)建。要注意的是該函數(shù)不能用于獲取由函數(shù) xSemaphoreCreateMutex() 創(chuàng)建的互斥量蝶柿。

函數(shù) #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) )
參數(shù) xMutex: 信號量句柄
xBlockTime: 如果不是持有互斥量的任務(wù)去獲取無效的互斥量鳖藕,那么任務(wù)將進行等待用戶指定超時時間,單位為 tick(即系統(tǒng)節(jié)拍周期)只锭。如果宏 INCLUDE_vTaskSuspend 定義為 1 且形參 xTicksToWait 設(shè)置為portMAX_DELAY 著恩,則任務(wù)將一直阻塞在該遞歸互斥量上(即沒有超時時間)
返回值 成功返回 pdTRUE,否則返回 errQUEUE_EMPTY

要想使用該函數(shù)必須在 FreeRTOSConfig.h 中把configUSE_RECURSIVE_MUTEXES 定義為 1 來使能。

3.6 xSemaphoreGive

用于釋放信號量的宏喉誊。釋放的信號量對象必須是已經(jīng)被創(chuàng)建的邀摆,可以用于二值信號量、計數(shù)信號量伍茄、互斥量的釋放栋盹,但不能釋放由函數(shù) xSemaphoreCreateRecursiveMutex() 創(chuàng)建的遞歸互斥量。此外該函數(shù)不能在中斷中使用敷矫。

函數(shù) xSemaphoreGive( SemaphoreHandle_t xSemaphore )
參數(shù) xSemaphore: 信號量句柄
返回值 成功返回 pdTRUE例获,否則返回 pdFALSE

3.7 xSemaphoreGiveRecursive

用于釋放一個遞歸互斥量。已經(jīng)獲取遞歸互斥量的任務(wù)可以重復(fù)獲取該遞歸互斥量曹仗。使用 xSemaphoreTakeRecursive() 函數(shù)成功獲取幾次遞歸互斥量榨汤,就要使用 xSemaphoreGiveRecursive() 函數(shù)返還幾次,在此之前遞歸互斥量都處于無效狀態(tài)怎茫,別的任務(wù)就無法獲取該遞歸互斥量收壕。使用該函數(shù)接口時,只有已持有互斥量所有權(quán)的任務(wù)才能釋放它轨蛤,每釋放一該遞歸互斥量蜜宪,它的計數(shù)值就減 1。當(dāng)該互斥量的計數(shù)值為 0 時(即持有任務(wù)已經(jīng)釋放所有的持有操作)祥山,互斥量則變?yōu)殚_鎖狀態(tài)圃验,等待在該互斥量上的任務(wù)將被喚醒。如果任務(wù)的優(yōu)先級被互斥量的優(yōu)先級翻轉(zhuǎn)機制臨時提升缝呕,那么當(dāng)互斥量被釋放后损谦,任務(wù)的優(yōu)先級將恢復(fù)為原本設(shè)定的優(yōu)先級。

函數(shù) #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) )
參數(shù) xMutex : 信號量句柄
返回值 成功返回 pdTRUE岳颇,否則返回 pdFALSE

要想使用該函數(shù)必須在 FreeRTOSConfig.h 中把configUSE_RECURSIVE_MUTEXES 定義為 1 來使能照捡。

四、示例

/* FreeRTOS 頭文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
/* 開發(fā)板硬件 bsp 頭文件 */
#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_key.h"
/**************************** 任務(wù)句柄 ********************************/
/*
* 任務(wù)句柄是一個指針话侧,用于指向一個任務(wù)栗精,當(dāng)任務(wù)創(chuàng)建好之后,它就具有了一個任務(wù)句柄
* 以后我們要想操作這個任務(wù)都需要通過這個任務(wù)句柄瞻鹏,如果是自身的任務(wù)操作自己悲立,那么
* 這個句柄可以為 NULL。
*/
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 創(chuàng)建任務(wù)句柄 */
static TaskHandle_t LowPriority_Task_Handle = NULL;/* LowPriority_Task 任務(wù)句柄 */
static TaskHandle_t MidPriority_Task_Handle = NULL;/* MidPriority_Task 任務(wù)句柄 */
static TaskHandle_t HighPriority_Task_Handle = NULL;/* HighPriority_Task 任務(wù)句柄 */
 
/***************************** 內(nèi)核對象句柄 *****************************/
/*
* 信號量新博,消息隊列薪夕,事件標(biāo)志組,軟件定時器這些都屬于內(nèi)核的對象赫悄,要想使用這些內(nèi)核
* 對象原献,必須先創(chuàng)建馏慨,創(chuàng)建成功之后會返回一個相應(yīng)的句柄。實際上就是一個指針姑隅,后續(xù)我
* 們就可以通過這個句柄操作這些內(nèi)核對象写隶。
*
* 內(nèi)核對象說白了就是一種全局的數(shù)據(jù)結(jié)構(gòu),通過這些數(shù)據(jù)結(jié)構(gòu)我們可以實現(xiàn)任務(wù)間的通信讲仰,
* 任務(wù)間的事件同步等各種功能慕趴。至于這些功能的實現(xiàn)我們是通過調(diào)用這些內(nèi)核對象的函數(shù)
* 來完成的
*
*/
SemaphoreHandle_t MuxSem_Handle = NULL;

static void AppTaskCreate(void);/* 用于創(chuàng)建任務(wù) */ 
static void LowPriority_Task(void* pvParameters);/* LowPriority_Task 任務(wù)實現(xiàn) */
static void MidPriority_Task(void* pvParameters);/* MidPriority_Task 任務(wù)實現(xiàn) */
static void HighPriority_Task(void* pvParameters);/* HighPriority_Task 任務(wù)實現(xiàn) */

static void BSP_Init(void);/* 用于初始化板載相關(guān)資源 */

int main(void)
{
    BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值,默認(rèn)為 pdPASS */

    /* 開發(fā)板硬件初始化 */
    BSP_Init();
    /* 創(chuàng)建 AppTaskCreate 任務(wù) */
    xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,/* 任務(wù)入口函數(shù) */
                          (const char* )"AppTaskCreate",/* 任務(wù)名字 */
                          (uint16_t )512, /* 任務(wù)棧大小 */
                          (void* )NULL,/* 任務(wù)入口函數(shù)參數(shù) */
                          (UBaseType_t )1, /* 任務(wù)的優(yōu)先級 */
                          (TaskHandle_t*)&AppTaskCreate_Handle);/* 任務(wù)控制塊指針 */
    /* 啟動任務(wù)調(diào)度 */
    if (pdPASS == xReturn)
    {
        vTaskStartScheduler(); /* 啟動任務(wù)鄙陡,開啟調(diào)度 */
    }
    else
    {
        return -1;
    } 

    while (1); /* 正常不會執(zhí)行到這里 */
}

/***********************************************************************
* @ 函數(shù)名 : AppTaskCreate
* @ 功能說明: 為了方便管理冕房,所有的任務(wù)創(chuàng)建函數(shù)都放在這個函數(shù)里面
* @ 參數(shù) : 無
* @ 返回值 : 無
***************************************************************/
static void AppTaskCreate(void)
{
    BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值,默認(rèn)為 pdPASS */
  
    taskENTER_CRITICAL(); //進入臨界區(qū)
   
    /* 創(chuàng)建 MuxSem */ 
    MuxSem_Handle = xSemaphoreCreateMutex();
    if (NULL != MuxSem_Handle) 
    {
        printf("MuxSem_Handle 互斥量創(chuàng)建成功!\r\n"); 
    }

    xReturn = xSemaphoreGive( MuxSem_Handle );//給出互斥量
  
    /* 創(chuàng)建 LowPriority_Task 任務(wù) */
    xReturn = xTaskCreate((TaskFunction_t )LowPriority_Task,/* 任務(wù)入口函數(shù) */
                          (const char* )"LowPriority_Task",/* 任務(wù)名字 */
                          (uint16_t )512, /* 任務(wù)棧大小 */
                          (void* )NULL, /* 任務(wù)入口函數(shù)參數(shù) */
                          (UBaseType_t )2, /* 任務(wù)的優(yōu)先級 */
                          (TaskHandle_t* )&LowPriority_Task_Handle);/* 任務(wù)控制塊指針 */
    if (pdPASS == xReturn)
    {
        printf("創(chuàng)建 LowPriority_Task 任務(wù)成功!\r\n");
    }
  
    /* 創(chuàng)建 MidPriority_Task 任務(wù) */
    xReturn = xTaskCreate((TaskFunction_t )MidPriority_Task,/* 任務(wù)入口函數(shù) */
                          (const char* )"MidPriority_Task",/* 任務(wù)名字 */
                          (uint16_t )512, /* 任務(wù)棧大小 */
                          (void* )NULL, /* 任務(wù)入口函數(shù)參數(shù) */
                          (UBaseType_t )2, /* 任務(wù)的優(yōu)先級 */
                          (TaskHandle_t* )&MidPriority_Task_Handle);/* 任務(wù)控制塊指針 */
    if (pdPASS == xReturn)
    {
        printf("創(chuàng)建 MidPriority_Task 任務(wù)成功!\r\n");
    }

    /* 創(chuàng)建 HighPriority_Task 任務(wù) */
    xReturn = xTaskCreate((TaskFunction_t )HighPriority_Task,/* 任務(wù)入口函數(shù) */
                          (const char* )"HighPriority_Task",/* 任務(wù)名字 */
                          (uint16_t )512, /* 任務(wù)棧大小 */
                          (void* )NULL, /* 任務(wù)入口函數(shù)參數(shù) */
                          (UBaseType_t )2, /* 任務(wù)的優(yōu)先級 */
                          (TaskHandle_t* )&HighPriority_Task_Handle);/* 任務(wù)控制塊指針 */
    if (pdPASS == xReturn)
    {
        printf("創(chuàng)建 HighPriority_Task 任務(wù)成功!\r\n");
    }

    vTaskDelete(AppTaskCreate_Handle); //刪除 AppTaskCreate 任務(wù)
    
    taskEXIT_CRITICAL(); //退出臨界區(qū)
}

/**********************************************************************
* @ 函數(shù)名 : LowPriority_Task
* @ 功能說明: LowPriority_Task 任務(wù)主體
* @ 參數(shù) :
* @ 返回值 : 無
********************************************************************/
static void LowPriority_Task(void* parameter) 
{ 
    static uint32_t i; 
    BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值趁矾,默認(rèn)為 pdPASS */ 
    while (1) 
    { 
        printf("LowPriority_Task 獲取信號量\n"); 
        //獲取互斥量 MuxSem,沒獲取到則一直等待 
        xReturn = xSemaphoreTake(MuxSem_Handle,/* 互斥量句柄 */ 
                                portMAX_DELAY); /* 等待時間 */ 
        if (pdTRUE == xReturn) 
        {
            printf("LowPriority_Task Runing\n\n"); 
        }

        for (i=0; i<2000000; i++) 
        { //模擬低優(yōu)先級任務(wù)占用互斥量 
            taskYIELD();//發(fā)起任務(wù)調(diào)度 
        } 

        printf("LowPriority_Task 釋放信號量!\r\n"); 
        xReturn = xSemaphoreGive( MuxSem_Handle );//給出互斥量 

        LED1_TOGGLE; 

        vTaskDelay(1000); 
    }
} 

/**********************************************************************
* @ 函數(shù)名 : MidPriority_Task
* @ 功能說明: MidPriority_Task 任務(wù)主體
* @ 參數(shù) :
* @ 返回值 : 無
********************************************************************/
static void MidPriority_Task(void* parameter) 
{ 
    while (1) 
    { 
        printf("MidPriority_Task Runing\n"); 
        vTaskDelay(1000); 
    } 
}

/**********************************************************************
* @ 函數(shù)名 : HighPriority_Task
* @ 功能說明: HighPriority_Task 任務(wù)主體
* @ 參數(shù) :
* @ 返回值 : 無
********************************************************************/
static void HighPriority_Task(void* parameter) 
{ 
    BaseType_t xReturn = pdTRUE;/* 定義一個創(chuàng)建信息返回值耙册,默認(rèn)為 pdPASS */ 
    while (1) 
    { 
        printf("HighPriority_Task 獲取信號量\n"); 
        //獲取互斥量 MuxSem,沒獲取到則一直等待 
        xReturn = xSemaphoreTake(MuxSem_Handle,/* 互斥量句柄 */ 
                                portMAX_DELAY); /* 等待時間 */ 
        if (pdTRUE == xReturn) 
        {
            printf("HighPriority_Task Runing\n"); 
        }
        LED1_TOGGLE; 
  
        printf("HighPriority_Task 釋放信號量!\r\n"); 
        xReturn = xSemaphoreGive( MuxSem_Handle );//給出互斥量  
   
        vTaskDelay(1000); 
    }
} 

/***********************************************************************
* @ 函數(shù)名 : BSP_Init
* @ 功能說明: 板級外設(shè)初始化,所有板子上的初始化均可放在這個函數(shù)里面
* @ 參數(shù) :
* @ 返回值 : 無
*********************************************************************/
static void BSP_Init(void)
{
    /*
    * STM32 中斷優(yōu)先級分組為 4愈魏,即 4bit 都用來表示搶占優(yōu)先級觅玻,范圍為:0~15
    * 優(yōu)先級分組只需要分組一次即可想际,以后如果有其他的任務(wù)需要用到中斷培漏,
    * 都統(tǒng)一用這個優(yōu)先級分組,千萬不要再分組胡本,切忌牌柄。
    */
    NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
   
    /* LED 初始化 */
    LED_GPIO_Config();
  
    /* 串口初始化 */
    USART_Config();
   
    /* 按鍵初始化 */
    Key_GPIO_Config();     
}

? 由 Leung 寫于 2020 年 11 月 23 日

? 參考:野火FreeRTOS視頻與PDF教程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市侧甫,隨后出現(xiàn)的幾起案子珊佣,更是在濱河造成了極大的恐慌,老刑警劉巖披粟,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咒锻,死亡現(xiàn)場離奇詭異,居然都是意外死亡守屉,警方通過查閱死者的電腦和手機惑艇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拇泛,“玉大人滨巴,你說我怎么就攤上這事“嘲龋” “怎么了恭取?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熄守。 經(jīng)常有香客問我蜈垮,道長耗跛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任窃款,我火速辦了婚禮课兄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘晨继。我一直安慰自己烟阐,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布紊扬。 她就那樣靜靜地躺著蜒茄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪餐屎。 梳的紋絲不亂的頭發(fā)上檀葛,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天,我揣著相機與錄音腹缩,去河邊找鬼屿聋。 笑死,一個胖子當(dāng)著我的面吹牛藏鹊,可吹牛的內(nèi)容都是我干的润讥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼盘寡,長吁一口氣:“原來是場噩夢啊……” “哼楚殿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起竿痰,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤脆粥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后影涉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體变隔,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年蟹倾,在試婚紗的時候發(fā)現(xiàn)自己被綠了匣缘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡喊式,死狀恐怖孵户,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岔留,我是刑警寧澤夏哭,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站献联,受9級特大地震影響竖配,放射性物質(zhì)發(fā)生泄漏何址。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一进胯、第九天 我趴在偏房一處隱蔽的房頂上張望用爪。 院中可真熱鬧,春花似錦胁镐、人聲如沸偎血。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颇玷。三九已至,卻和暖如春就缆,著一層夾襖步出監(jiān)牢的瞬間帖渠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工竭宰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留空郊,地道東北人。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓切揭,卻偏偏與公主長得像狞甚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子伴箩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,665評論 2 354

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