談一談iOS開(kāi)發(fā)中的"鎖"

關(guān)于“鎖”
iOS中的鎖,也叫線程鎖。是為了在多線程操作中侠讯,防止同一時(shí)間多個(gè)線程對(duì)共享資源進(jìn)行讀寫(xiě)操作而引入的一種機(jī)制。例如并行隊(duì)列里的異步任務(wù)暑刃,有可能存在多個(gè)線程同時(shí)讀寫(xiě)某一個(gè)對(duì)象的操作厢漩。如線程1正在執(zhí)行寫(xiě)操作,此時(shí)線程2需要執(zhí)行讀操作稍走,如此執(zhí)行線程2獲取到的數(shù)據(jù)肯定是一個(gè)錯(cuò)誤的數(shù)據(jù)袁翁。因此柴底,為了防止這種情況的發(fā)生婿脸,需要引入一種“在同一時(shí)間片段內(nèi)只能有一個(gè)線程在對(duì)共享資源執(zhí)行讀寫(xiě)操作、而時(shí)間片段結(jié)束后能恢復(fù)到多個(gè)線程同時(shí)對(duì)共享資源執(zhí)行讀寫(xiě)操作的機(jī)制”柄驻。而這種機(jī)制狐树,就是我們所說(shuō)的鎖。
“鎖”的作用
在同一時(shí)間段片內(nèi)鸿脓、只允許一個(gè)線程對(duì)某一共享資源執(zhí)行讀寫(xiě)操作抑钟。
需要注意的是:鎖只是改變了鎖內(nèi)共享資源的讀寫(xiě)在時(shí)間片內(nèi)只能有一個(gè)線程去訪問(wèn),但并不會(huì)改變其它線程的執(zhí)行野哭。也就是說(shuō)只有遇到多個(gè)線程同時(shí)訪問(wèn)共享資源的時(shí)候在塔,線程只能一個(gè)一個(gè)的去執(zhí)行。而其它沒(méi)有訪問(wèn)到共享資源的線程拨黔,則依舊是并發(fā)執(zhí)行的蛔溃。

“鎖”的種類
在iOS開(kāi)發(fā)中,NSLock、@synchronized應(yīng)該是我們接觸的最早和做多的一種鎖贺待。至于NSConditionLock徽曲、NSRecursiveLock等一系列的鎖,也會(huì)給大家一一介紹麸塞。
NSLock:普通鎖秃臣,其用法可參見(jiàn)其頭文件。

為2個(gè)方法1個(gè)屬性哪工,以及1個(gè)協(xié)議奥此。2個(gè)方法分別為“嘗試上鎖”、“在某個(gè)時(shí)間之前鎖住”雁比;name則為鎖的名字得院。其所包含的NSLocking協(xié)議,有2個(gè)方法章贞,分別為“上鎖”和“解鎖”祥绞。
其基本用法如下所示:

//自定義并行隊(duì)列
dispatch_queue_tqueue = dispatch_queue_create("com.jiadai.demoOfLock", DISPATCH_QUEUE_CONCURRENT);if(type ==0) {//NSLockNSLock*lock = [[NSLockalloc]init];
__blockinta =0;dispatch_async(queue, ^{NSLog(@"線程1開(kāi)始任務(wù)");
[lock lock];for(inti =0; i<5; i++) {
sleep(1);
a = a +1;NSLog(@"線程1執(zhí)行任務(wù)a = %d",a);if(i==4) {
sleep(1);
}
}
[lock unlock];NSLog(@"線程1解鎖成功");
});dispatch_async(queue, ^{NSLog(@"線程2開(kāi)始任務(wù)");
[lock lock];for(inti =0; i<3; i++) {
sleep(1);
a = a +1;NSLog(@"線程2執(zhí)行任務(wù)a = %d",a);if(i==2) {
sleep(1);
}
}
[lock unlock];NSLog(@"線程2解鎖成功");
});
}

這里自定義了一個(gè)并行異步線程,同事定義了一個(gè)共享資源a鸭限,并且給2個(gè)線程里的任務(wù)都給上鎖蜕径。那么在上鎖之前,2個(gè)任務(wù)理論上應(yīng)該是同時(shí)啟動(dòng)的败京。當(dāng)執(zhí)行鎖的操作時(shí)兜喻,由于只能允許一個(gè)線程執(zhí)行任務(wù),那么這里就有可能任務(wù)1在執(zhí)行也有可能任務(wù)2在執(zhí)行赡麦,總的來(lái)說(shuō)只能有一個(gè)任務(wù)在執(zhí)行朴皆。執(zhí)行結(jié)束后,2個(gè)線程的任務(wù)都執(zhí)行解鎖操作泛粹,線程的任務(wù)又可以回到并行異步了遂铡。我們可參見(jiàn)執(zhí)行的結(jié)果來(lái)進(jìn)一步說(shuō)明鎖是怎么工作的。

可以看得到晶姊,在給線程1和線程2里的任務(wù)都上鎖的情況下扒接,同一時(shí)間片段內(nèi)只能有一個(gè)任務(wù)執(zhí)行,這就保證了操作的互斥性们衙。也就是共享資源钾怔,單次只能執(zhí)行一個(gè)a=a+1的操作。
如果我們?nèi)サ艟€程1或者線程2里的鎖蒙挑,或者去掉全部的鎖宗侦,那么其執(zhí)行窗市,則會(huì)根據(jù)當(dāng)前時(shí)間點(diǎn)拿到的a的值進(jìn)行a=a+1的操作稻据。
例如我們?nèi)サ艟€程2里的鎖

dispatch_async(queue, ^{NSLog(@"線程2開(kāi)始任務(wù)");//    [lock lock];for(inti =0; i<3; i++) {
sleep(1);
a = a +1;NSLog(@"線程2執(zhí)行任務(wù)a = %d",a);if(i==2) {
sleep(1);
}
}//    [lock unlock];NSLog(@"線程2解鎖成功");
});

其執(zhí)行的結(jié)果:

顯而易見(jiàn),線程2的執(zhí)行并沒(méi)有因?yàn)榫€程1的鎖而受到干擾窗悯。其執(zhí)行時(shí)間與線程1一致,都是間隔1秒執(zhí)行一次梦皮。其執(zhí)行時(shí)的a炭分,為其當(dāng)前時(shí)刻拿到的a(可能先于線程1執(zhí)行,也可能后于線程1執(zhí)行)剑肯。同理線程1的執(zhí)行捧毛,也沒(méi)有受到線程2的影響。
對(duì)于tryLock和lockBeforeDate:(NSDate *)limit让网,2個(gè)方法都是返回BOOL值呀忧。tryLock表示嘗試加鎖,lockBeforeDate則表示在某個(gè)時(shí)間點(diǎn)之前加鎖溃睹。返回YES則表示加鎖成功而账,并在鎖內(nèi)執(zhí)行方法;否則表示加鎖失敗因篇,方法在無(wú)鎖條件下執(zhí)行泞辐。
@synchronized:其用法還是相當(dāng)簡(jiǎn)單的,代碼如下竞滓。

//@synchronized__blockintb1 =0;
__blockintb2 =0;dispatch_async(queue, ^{NSLog(@"線程1開(kāi)始任務(wù)");@synchronized(self) {for(inti =0; i<3; i++) {
sleep(1);
b1 = b1 +1;NSLog(@"線程1執(zhí)行任務(wù)b1 = %d",b1);if(i==2) {
sleep(1);
}
}
}
});dispatch_async(queue, ^{NSLog(@"線程2開(kāi)始任務(wù)");@synchronized(self) {for(inti =0; i<3; i++) {
sleep(1);
b2 = b2 +1;NSLog(@"線程2執(zhí)行任務(wù)b2 = %d",b2);if(i==2) {
sleep(1);
}
}
}
});

在這里咐吼,我定義了2個(gè)異步任務(wù)和2個(gè) 對(duì)象b1、b2商佑,并且執(zhí)行+1操作锯茄。在加鎖之前,2個(gè)任務(wù)應(yīng)該是同時(shí)啟動(dòng)并開(kāi)始執(zhí)行茶没;加鎖之后肌幽,由于2個(gè)子線程的任務(wù)都是加鎖執(zhí)行的,那么在單位時(shí)間內(nèi)只能一個(gè)一個(gè)的執(zhí)行了抓半。結(jié)果如下圖所示:

可看到2個(gè)加鎖的異步任務(wù)喂急,在單位時(shí)間內(nèi)是依次執(zhí)行的。如果去掉其中一個(gè)線程的鎖琅关,則另一個(gè)線程的執(zhí)行并不會(huì)受到加鎖線程的影響煮岁。其執(zhí)行效果,類似于NSLock涣易。
NSConditionLock:條件鎖,其用法可參見(jiàn)其頭文件冶伞。

其用法跟NSLock類似新症,為tryLock和lockBeforeDate。但相對(duì)NSLock多了個(gè)conditon响禽。我們可以通過(guò)具體實(shí)例來(lái)進(jìn)一步了解NSConditionLock的用法徒爹。

//NSConditionLockNSConditionLock*lock = [[NSConditionLockalloc]initWithCondition:0];
__blockintc =0;dispatch_async(queue, ^{NSLog(@"線程1開(kāi)始任務(wù)");
[lock lockWhenCondition:0];for(inti =0; i<3; i++) {
sleep(1);
c = c +1;NSLog(@"線程1執(zhí)行任務(wù)c = %d",c);
}
[lock unlockWithCondition:1];
});dispatch_async(queue, ^{NSLog(@"線程2開(kāi)始任務(wù)");
[lock lockWhenCondition:1];for(inti =0; i<3; i++) {
sleep(1);
c = c +1;NSLog(@"線程2執(zhí)行任務(wù)c = %d",c);
}
[lock unlockWithCondition:2];
});dispatch_async(queue, ^{NSLog(@"線程3開(kāi)始任務(wù)");
[lock lockWhenCondition:2];for(inti =0; i<3; i++) {
sleep(1);
c = c +1;NSLog(@"線程3執(zhí)行任務(wù)c = %d",c);
}
[lock unlockWithCondition:3];
});

首先我們創(chuàng)建了一個(gè)條件鎖荚醒,并且設(shè)定起始條件condition=0。隨后創(chuàng)建了3個(gè)異步任務(wù)隆嗅,并且其任務(wù)是在鎖內(nèi)執(zhí)行的界阁。所以,3個(gè)線程鎖內(nèi)的任務(wù)胖喳,在同一時(shí)間片段內(nèi)只能有一個(gè)在執(zhí)行泡躯。當(dāng)condition=0的時(shí)候,線程1的任務(wù)加鎖丽焊,并且在線程1的任務(wù)執(zhí)行完畢后才執(zhí)行解鎖操作较剃。在解鎖的時(shí)候,給condition重新賦值技健。而此時(shí)線程2滿足加鎖條件写穴,則線程2的任務(wù)會(huì)被立即執(zhí)行。同理雌贱,當(dāng)其它線程滿足加鎖操作時(shí)啊送,則其內(nèi)的任務(wù)也會(huì)被立即執(zhí)行。需要注意的是欣孤,加鎖和解鎖需成對(duì)出現(xiàn)删掀,否則會(huì)造成一些錯(cuò)誤。
其運(yùn)行結(jié)果如下圖所示:

由于NSConditionLock也遵循NSLocking協(xié)議导街,所以可像NSLock那樣直接使用lock和unlock對(duì)任務(wù)執(zhí)行加鎖解鎖操作披泪。
對(duì)于其它幾個(gè)方法,需要根據(jù)返回的BOOL值進(jìn)行判斷是否加鎖成功搬瑰。如果加鎖成功款票,則在方法執(zhí)行完后進(jìn)行解鎖。若沒(méi)有成功泽论,那就不需要解鎖艾少,否則會(huì)造成一些錯(cuò)誤。例如try加鎖成功翼悴,則執(zhí)行鎖的方法缚够,結(jié)束后進(jìn)行解鎖。加鎖失敗鹦赎,則另行處理谍椅。
NSRecursiveLock:遞歸鎖,其用法可參見(jiàn)其頭文件古话。

其用法與NSConditionLock類似雏吭,為tryLock和lockBeforeDate。

//NSRecursiveLockNSRecursiveLock*lock = [[NSRecursiveLockalloc]init];dispatch_async(queue, ^{staticvoid(^MyMethod)(int);
MyMethod = ^(intval){
[lock lock];if(val >0) {
sleep(1);NSLog(@"執(zhí)行任務(wù)val=%d",val);
MyMethod(val-1);
}
[lock unlock];
};
MyMethod(5);
});

例如遞歸方法MyMethod陪踩,內(nèi)有有判斷杖们,當(dāng)val>0的時(shí)候悉抵,則會(huì)重新調(diào)用自身。如果是普通鎖摘完,則會(huì)先執(zhí)行l(wèi)ock姥饰,后又執(zhí)行MyMethod,并嘗試lock孝治。但由于該線程內(nèi)已經(jīng)有一個(gè)lock在執(zhí)行任務(wù)列粪,重新加鎖則會(huì)造成死鎖。此時(shí)選用遞歸鎖荆秦,則允許該線程可被多次lock篱竭,并且在執(zhí)行unlock的時(shí)候,移除所有的lock步绸。
其運(yùn)行結(jié)果如下圖所示:

若將NSConditionLock換成普通的NSLock掺逼,其執(zhí)行結(jié)果如下:

當(dāng)執(zhí)行第二次MyMethod時(shí),發(fā)生死鎖(當(dāng)前線程已存在一個(gè)鎖瓤介,無(wú)法再添加新的鎖)吕喘。
NSCondition:條件鎖,其用法可參見(jiàn)其頭文件刑桑。

其主要提供2個(gè)方法氯质,wait(等待)和signal(發(fā)送信號(hào))。同時(shí)遵循NSLocking協(xié)議祠斧,所以可直接使用lock和unlock方法闻察。
其主要特點(diǎn)為線程任務(wù)等待發(fā)送信號(hào)喚醒等待中的任務(wù)。具體用法如下所示:

//NSCondition
__blockintd =0;
NSCondition*lock = [[NSConditionalloc]init];
dispatch_async(queue, ^{//上鎖琢锋,并等待[lock lock];
if(d ==0) {
//等待
NSLog(@"線程等待");
[lock wait];
}
//執(zhí)行任務(wù)
2d = d+1;
NSLog(@"執(zhí)行條件任務(wù)2d=%d",d);
//解鎖
[lock unlock];
});dispatch_async(queue, ^{
//上鎖
[lock lock];
d = d +1;
//執(zhí)行任務(wù)1
NSLog(@"執(zhí)行線程任務(wù)1d=%d",d);
//發(fā)送信號(hào)辕漂,通知等待中的線程
NSLog(@"發(fā)送信號(hào)");
[lock signal];
//解鎖
[lock unlock];
});

首先,我們創(chuàng)建了一個(gè)條件鎖吴超,并初始化一個(gè)數(shù)據(jù)d = 0钉嘹。然后我們創(chuàng)建了2個(gè)異步任務(wù),在線程2里鲸阻,進(jìn)行判斷:如果d = 0跋涣,那么線程等待;否則執(zhí)行線程2任務(wù)鸟悴。在線程1里陈辱,我們給任務(wù)上鎖,并執(zhí)行d = d+1的操作遣臼。操作完成后性置,發(fā)送信號(hào)激活處于等待的任務(wù)并對(duì)線程1進(jìn)行解鎖。而此時(shí)揍堰,線程2在收到信號(hào)后鹏浅,在線程1解鎖完成后,執(zhí)行內(nèi)部任務(wù)屏歹,并進(jìn)行線程2解鎖隐砸。從而完成整個(gè)加鎖、等待蝙眶、執(zhí)行任務(wù)季希、發(fā)送信號(hào)、執(zhí)行任務(wù)幽纷、解鎖等過(guò)程式塌。
對(duì)于NSCondition,我們重點(diǎn)需要掌握其線程等待和發(fā)送信號(hào)激活等待線程等方法友浸。
OSSpinLock:自旋鎖
需要導(dǎo)入頭文件:

import<libkern/OSAtomic.h>

具體用法如下圖所示:

//OSSpinLock__block OSSpinLock lock = OS_SPINLOCK_INIT;
__blockinte =0;dispatch_async(queue, ^{
OSSpinLockLock(&lock);for(inti =0; i<3; i++) {
sleep(1);
e = e +1;NSLog(@"線程1執(zhí)行任務(wù)e = %d",e);
}
OSSpinLockUnlock(&lock);
});dispatch_async(queue, ^{
OSSpinLockLock(&lock);for(inti =0; i<3; i++) {
sleep(1);
e = e +1;NSLog(@"線程2執(zhí)行任務(wù)e = %d",e);
}
OSSpinLockUnlock(&lock);
});
其執(zhí)行結(jié)果如下:

`

可見(jiàn)其用法及執(zhí)行結(jié)果峰尝,與NSLock類似。但OSSpinLock已不在安全收恢,在iOS10中首次被遺棄(不建議使用)武学。
pthread_mutex:互斥鎖
需要導(dǎo)入頭文件:

import<pthread.h>

具體用法如下圖所示:

//pthread_mutex 互斥鎖staticpthread_mutex_t lock;
__blockintf =0;
pthread_mutex_init(&lock,NULL);dispatch_async(queue, ^{
pthread_mutex_lock(&lock);for(inti =0; i<3; i++) {
sleep(1);
f = f +1;NSLog(@"線程1執(zhí)行任務(wù)f = %d",f);
}
pthread_mutex_unlock(&lock);
});dispatch_async(queue, ^{
pthread_mutex_lock(&lock);for(inti =0; i<3; i++) {
sleep(1);
f = f +1;NSLog(@"線程2執(zhí)行任務(wù)f = %d",f);
}
pthread_mutex_unlock(&lock);
});

其執(zhí)行結(jié)果如下:

可見(jiàn)其用法及執(zhí)行結(jié)果,與NSLock類似伦意,加鎖解鎖成對(duì)出現(xiàn)火窒。
pthread_mutex(recursive):遞歸鎖。
與pthread_mutex類似驮肉,使用場(chǎng)景與NSRecursiveLock相同熏矿,都是用于單個(gè)線程內(nèi)多次進(jìn)行加鎖操作。具體用法如下所示:

staticpthread_mutex_t lock;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);//初始化attr并且給它賦予默認(rèn)pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);//設(shè)置鎖類型离钝,這邊是設(shè)置為遞歸鎖pthread_mutex_init(&lock, &attr);
pthread_mutexattr_destroy(&attr);//銷(xiāo)毀一個(gè)屬性對(duì)象票编,在重新進(jìn)行初始化之前該結(jié)構(gòu)不能重新使用dispatch_async(queue, ^{staticvoid(^MyMethod)(int);
MyMethod = ^(intval){
pthread_mutex_lock(&lock);if(val >0) {
sleep(1);NSLog(@"執(zhí)行任務(wù)val=%d",val);
MyMethod(val-1);
}
pthread_mutex_unlock(&lock);
};
MyMethod(5);
});

其執(zhí)行結(jié)果如下:

dispatch_semaphore:信號(hào)量。
其用法與NSCondition有些類似:等待奈辰、發(fā)送信號(hào)栏妖、喚醒等待的任務(wù)。具體使用如下所示:

dispatch_semaphore_t signal = dispatch_semaphore_create(2);
dispatch_time_t overTime = dispatch_time(DISPATCH_TIME_NOW,3.0f *NSEC_PER_SEC);dispatch_async(queue, ^{
dispatch_semaphore_wait(signal, overTime);
sleep(1);
NSLog(@"執(zhí)行線程1任務(wù)");
dispatch_semaphore_signal(signal);
});dispatch_async(queue, ^{
dispatch_semaphore_wait(signal, overTime);
sleep(1);
NSLog(@"執(zhí)行線程2任務(wù)");
dispatch_semaphore_signal(signal);
});
dispatch_async(queue, ^{
dispatch_semaphore_wait(signal, overTime);
sleep(1);
NSLog(@"執(zhí)行線程3任務(wù)");
dispatch_semaphore_signal(signal);
});

其執(zhí)行結(jié)果如下:

需要注意的是:在信號(hào)量創(chuàng)建的時(shí)候奖恰,需要帶上一個(gè)并發(fā)執(zhí)行數(shù)吊趾。例如此處我設(shè)置的是1,那單位時(shí)間片內(nèi)只能有一個(gè)線程在執(zhí)行瑟啃。同時(shí)论泛,線程等待需要傳入等待時(shí)間;表示在等待多少時(shí)間后蛹屿,就會(huì)執(zhí)行線程方法屁奏。
性能對(duì)比
鎖的性能,如下圖所示:

總結(jié)
對(duì)于iOS中的鎖错负,需要理解鎖的概念和鎖的作用:是一種解決多線程中共享資源間的互斥訪問(wèn)的一種機(jī)制坟瓢;鎖的使用勇边,會(huì)降低多線程訪問(wèn)同一資源時(shí)執(zhí)行的效率,但是很好的解決了不同線程安全的訪問(wèn)同一資源的問(wèn)題折联;需要注意的是粒褒,同一時(shí)間片內(nèi),只能有一個(gè)加鎖的任務(wù)在執(zhí)行诚镰。而那些沒(méi)有加鎖的并行異步線程任務(wù)奕坟,則仍是多個(gè)線程同時(shí)執(zhí)行的;對(duì)于鎖清笨,還需要記住常用的幾種鎖以及各種鎖之間的差異與使用場(chǎng)景月杉,這對(duì)于我們?cè)诙嗑€程開(kāi)發(fā)中對(duì)于資源的安全性將會(huì)更有幫助。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末抠艾,一起剝皮案震驚了整個(gè)濱河市苛萎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌跌帐,老刑警劉巖首懈,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異谨敛,居然都是意外死亡究履,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)脸狸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)最仑,“玉大人,你說(shuō)我怎么就攤上這事炊甲∧嗤” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵卿啡,是天一觀的道長(zhǎng)吟吝。 經(jīng)常有香客問(wèn)我,道長(zhǎng)颈娜,這世上最難降的妖魔是什么剑逃? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮官辽,結(jié)果婚禮上蛹磺,老公的妹妹穿的比我還像新娘。我一直安慰自己同仆,他們只是感情好萤捆,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般俗或。 火紅的嫁衣襯著肌膚如雪市怎。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,696評(píng)論 1 312
  • 那天蕴侣,我揣著相機(jī)與錄音焰轻,去河邊找鬼臭觉。 笑死昆雀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蝠筑。 我是一名探鬼主播狞膘,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼什乙!你這毒婦竟也來(lái)了挽封?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤臣镣,失蹤者是張志新(化名)和其女友劉穎辅愿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體忆某,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡点待,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了弃舒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片癞埠。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖聋呢,靈堂內(nèi)的尸體忽然破棺而出苗踪,到底是詐尸還是另有隱情,我是刑警寧澤削锰,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布通铲,位于F島的核電站,受9級(jí)特大地震影響器贩,放射性物質(zhì)發(fā)生泄漏颅夺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一磨澡、第九天 我趴在偏房一處隱蔽的房頂上張望碗啄。 院中可真熱鬧,春花似錦稳摄、人聲如沸稚字。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)胆描。三九已至瘫想,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間昌讲,已是汗流浹背国夜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留短绸,地道東北人车吹。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像醋闭,于是被迫代替她去往敵國(guó)和親窄驹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

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