五俯邓、進(jìn)程間通信

  1. 信號(hào)

    • 信號(hào)是linux操作系統(tǒng)進(jìn)程間通信的一種方式骡楼,一個(gè)應(yīng)用進(jìn)程可以接受、發(fā)送信號(hào)給另一個(gè)進(jìn)程稽鞭,當(dāng)進(jìn)程捕獲到某個(gè)信號(hào)時(shí)鸟整,可以執(zhí)行某些特定的動(dòng)作。
    • 與信號(hào)操作有關(guān)的函數(shù)位于signal.h頭文件中朦蕴,一個(gè)重要的函數(shù)聲明如下



      該函數(shù)設(shè)置sig表示的信號(hào)由func表示的函數(shù)來(lái)處理篮条,返回一個(gè)與func同類(lèi)型的函數(shù)弟头,或以下兩個(gè)信號(hào)之一


    • 一個(gè)簡(jiǎn)單的例子
      #include<stdio.h>
      #include<signal.h>
      #include<stdlib.h>
      #include<unistd.h>
      void ouch(int sig){
          printf("Oh, I got signal %d\n", sig);
          (void) signal(SIGINT, SIG_DFL);
      }
      int main(){
          (void) signal(SIGINT, ouch);
          while(1){
              printf("hello world!\n");
              sleep(1);
          }
      }
      
    • 可以使用kill函數(shù)向指定進(jìn)程發(fā)送信號(hào)



      看一個(gè)簡(jiǎn)單的例子

      #include<stdio.h>
      #include<stdlib.h>
      #include<signal.h>
      #include<sys/types.h>
      #include<unistd.h>
      static int alarm_handled = 0;
      void ding(int sig){
          alarm_handled = 1;
      }
      int main(){
          printf("process %d starting...\n", getpid());
          (void) signal(SIGALRM, ding);
          switch(fork()){
              case -1:
                  perror("create process failed!");
                  break;
              case 0:
                  sleep(2);
                  kill(getppid(), SIGALRM);
                  exit(0);
                  break;
          }
          printf("waiting for SIGALRM...\n");
          pause();
          if(alarm_handled){
              printf("catched the alarm sig!\n");
          }
          return 0;
      }
      
    • 使用更加健壯的signal接口,sigaction




      使用sigaction改寫(xiě)第一個(gè)例子

      #include<stdio.h>
      #include<stdlib.h>
      #include<sys/types.h>
      #include<unistd.h>
      #include<signal.h>
      void ouch(int sig){
          printf("Oh, I got sig %d\n", sig);
          (void)signal(SIGINT, SIG_DFL);
      }
      int main(){
          struct sigaction act;
          act.sa_handler = ouch;
          act.sa_flags = 0;
          sigemptyset(&act.sa_mask);
          sigaction(SIGINT, &act, 0);
          while(1){
              printf("Hello world!\n");
              sleep(1);
          }
          return 0;
      }
      
    • 還需要了解一些操作sigset_t的一些函數(shù)






  2. 管道-pipe
    管道是應(yīng)用進(jìn)程之間的單向數(shù)據(jù)通道涉茧,進(jìn)程可以通過(guò)管道發(fā)送數(shù)據(jù)給另一個(gè)進(jìn)程赴恨,通過(guò)popen系統(tǒng)調(diào)用,可以打開(kāi)一個(gè)連接某個(gè)程序的管道伴栓,可以是r伦连,也可以是w



    一個(gè)讀取信息的例子

    #include<stdio.h>
    #include<stdlib.h>
    int main(){
        char info[50];
        FILE* fp = popen("uname -a", "r");
        if(fp == NULL){
            perror("create pipe to uname failed!");
            exit(0);
        }
        int num = fread(info, sizeof(char), 50, fp);
        printf("got information: - \n%s\n", info);
        return 0;
    }
    

    一個(gè)寫(xiě)數(shù)據(jù)的例子

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    int main(){
        FILE* fp_write = popen("od -c", "w");
        char info[50];
        sprintf(info, "once upon a time, there was ...");
        if(fp_write != NULL){
            fwrite(info, sizeof(char), strlen(info), fp_write);
            pclose(fp_write);
        }
        return 0;
    }
    

    一個(gè)讀取更多數(shù)據(jù)的例子

    #include<stdio.h>
    #include<stdlib.h>
    int main(){
        FILE* fp_read = popen("ps -ax", "r");
        if(fp_read == NULL){
            perror("create pipe to ps failed");
            exit(EXIT_FAILURE);
        }
        char info[1024];
        int num_char = fread(info, sizeof(char), 1024, fp_read);
        while(num_char>0){
            info[num_char - 1] = '\0';
            printf("got info: - \n%s\n", info);
            num_char = fread(info, sizeof(char), 1024, fp_read);
        }
        pclose(fp_read);
        exit(EXIT_SUCCESS);
    }
    

    一個(gè)重要的系統(tǒng)調(diào)用是pipe,如同shell中的管道操作符



    初始化兩個(gè)文件描述符組成的數(shù)組钳垮,一個(gè)用于讀惑淳,一個(gè)用于寫(xiě),一個(gè)簡(jiǎn)單的例子如下

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<string.h>
    #include<sys/types.h>
    int main(){
        int fd[2];
        char buf[200];
        int chpid;
        int len;
        //使用pipe系統(tǒng)調(diào)用創(chuàng)建一個(gè)管道扔枫,fd[0]用于讀取汛聚,fd[1]用于寫(xiě)入
        if(pipe(fd) == -1){
            perror("創(chuàng)建管道出錯(cuò):");
            exit(1);
        }
        if((chpid = fork()) == 0){
            close(fd[1]);
            //從fd[0]中讀取數(shù)據(jù)到buf緩沖區(qū)
            len = read(fd[0], buf, sizeof(buf));
            buf[len] = 0;
            printf("子進(jìn)程從管道讀取數(shù)據(jù):%s\n", buf);
            exit(0);
        }else{
            close(fd[0]);
            //sprintf函數(shù)將格式化數(shù)據(jù)寫(xiě)入緩沖區(qū)中
            sprintf(buf, "父進(jìn)程為子進(jìn)程(pid=%d)創(chuàng)建的數(shù)據(jù)锹安!\n", chpid);
            //使用write系統(tǒng)調(diào)用將buf中的數(shù)據(jù)寫(xiě)入fd[1]指向的管道中
            write(fd[1], buf, strlen(buf));
            exit(0);
        }
        return 0;
    }
    

    如上短荐,pipe創(chuàng)建的管道操作符僅僅用于相互有聯(lián)系的一組進(jìn)程,比如叹哭,父子進(jìn)程忍宋。當(dāng)我們?cè)跊](méi)有特殊聯(lián)系的進(jìn)程中想要相互聯(lián)系,可以通過(guò)命名管道fifo风罩,fifo是linux操作系統(tǒng)中一類(lèi)特殊的文件,用于進(jìn)程間通信



    mode_t可以取



    看一個(gè)生產(chǎn)者與消費(fèi)者的例子
    fifo_producer.c
    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<string.h>
    #include<fcntl.h>
    #include<limits.h>
    #define BUF_SIZE 4096
    #define TEN_SEG (1024 * 10)
    
    #define FIFO_NAME "/tmp/my_fifo"
    int main(){
        int open_mode = O_WRONLY;
        int fifo_fd;
        int res;
        char buf[BUF_SIZE + 1];
        if(access(FIFO_NAME, F_OK) == -1){
            res = mkfifo(FIFO_NAME, 0777);
            if(res == -1){
                fprintf(stderr, "can't create fifo file %s\n", FIFO_NAME);
                exit(EXIT_FAILURE);
            }
        }
        printf("process %d open fifo O_WRONLY!\n", getpid());
        fifo_fd = open(FIFO_NAME, open_mode);
        printf("process %d result %d\n", getpid(), fifo_fd);
        int bytes_sent = 0;
        if(fifo_fd != -1){
            do{
                res = write(fifo_fd, buf, BUF_SIZE);
                if(res == -1){
                    perror("error write data to fifo file");
                    exit(EXIT_FAILURE);
                }
                bytes_sent += res;
            }while(bytes_sent < TEN_SEG);
            (void)close(fifo_fd);
        }else{
            exit(EXIT_FAILURE);
        }
        printf("process %d finished\n%d bytes sent!", getpid(), bytes_sent);
        exit(EXIT_SUCCESS);
    }
    

    fifo_consumer.c

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<string.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<limits.h>
    #include<fcntl.h>
    #define BUF_SIZE 4096
    #define FIFO_NAME "/tmp/my_fifo"
    int main(){
        int res;
        int pipe_fd;
        int mode = O_RDONLY;
        if(access(FIFO_NAME, F_OK) == -1){
            perror("fifo file not exists! exiting...");
            exit(EXIT_FAILURE);
        }
        char recv[BUF_SIZE + 1];
        int bytes_recv;
        printf("process %d open fifo file with mode O_RDONLY!\n", getpid());
        pipe_fd = open(FIFO_NAME, mode);
        printf("open fifo file with result %d\n", pipe_fd);
        if(pipe_fd != -1){
            do{
                res = read(pipe_fd, recv, BUF_SIZE);
                bytes_recv += res;
            }while(res > 0);
            printf("%d bytes received!\n", bytes_recv);
            close(pipe_fd);
        }else{
            exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
    }
    

    result



    命名管道可用于多個(gè)進(jìn)程間相互通信糠排,客戶機(jī)服務(wù)器模式程序示例如下
    client.h

    #include<stdio.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<string.h>
    #include<limits.h>
    #include<fcntl.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    
    #define SERVER_FIFO_NAME "/tmp/server_fifo"
    #define CLIENT_FIFO_NAME "/tmp/cli_%d_fifo"
    
    #define BUF_SIZE 50
    struct data_to_pass_st{
        pid_t pid;
        char some_data[BUF_SIZE - 1];
    };
    

    server.c

    #include"client.h"
    #include<ctype.h>
    int main(){
        int serv_fifo_fd, cli_fifo_fd;
        struct data_to_pass_st data;
        char buf[BUF_SIZE];
        char cli_fifo_name[50];
        int mode_serv;
        int mode_cli;
        serv_fifo_fd = mkfifo(SERVER_FIFO_NAME, 0777);
        if(serv_fifo_fd == -1){
            perror("create server fifo failed!");
            exit(EXIT_FAILURE);
        }
        puts("create server fifo");
    
        mode_serv = O_RDONLY;
        serv_fifo_fd = open(SERVER_FIFO_NAME, mode_serv);
        if(serv_fifo_fd == -1){
            perror("open server fifo failed!");
            exit(EXIT_FAILURE);
        }
        puts("open server fifo");
    
        sleep(1);
    
        printf("read to receive data!\n");
        int read_bytes;
        char* tmp_ptr;
        do{
            read_bytes = read(serv_fifo_fd, &data, sizeof(data));
            if(read_bytes > 0){
                tmp_ptr = data.some_data;
                while(*tmp_ptr){
                    *tmp_ptr = toupper(*tmp_ptr);
                    tmp_ptr++;
                }
                sprintf(cli_fifo_name, CLIENT_FIFO_NAME, data.pid);
                cli_fifo_fd = open(cli_fifo_name, O_WRONLY);
                if(cli_fifo_fd != -1){
                    write(cli_fifo_fd, &data, sizeof(data));
                    close(cli_fifo_fd);
                }
            }
        }while(read_bytes > 0);
        close(serv_fifo_fd);
        unlink(SERVER_FIFO_NAME);
        exit(EXIT_SUCCESS);
    }
    

    client.c

    #include"client.h"
    #include<ctype.h>
    int main(){
        struct data_to_pass_st data;
        char buf[BUF_SIZE];
        char cli_fifo_name[50];
        int serv_fifo_fd, cli_fifo_fd;
    
    
        serv_fifo_fd = open(SERVER_FIFO_NAME, O_WRONLY);
        puts("client : open server fifo");
        if(serv_fifo_fd == -1){
            perror("open server fifo failed");
            exit(EXIT_FAILURE);
        }
    
        data.pid = getpid();
        sprintf(cli_fifo_name, CLIENT_FIFO_NAME, data.pid);
        mkfifo(cli_fifo_name, 0777);
        puts("client : create client fifo");
    
        int read_bytes;
    
        sprintf(data.some_data, "data from %d", data.pid);
        printf("%d sent: %s, ", data.pid, data.some_data);
        write(serv_fifo_fd, &data, sizeof(data));
    
        cli_fifo_fd = open(cli_fifo_name, O_RDONLY);
        if(cli_fifo_fd == -1){
            perror("open client fifo failed");
            exit(EXIT_FAILURE);
        }
        if(cli_fifo_fd != -1){
            read_bytes = read(cli_fifo_fd, &data, sizeof(data));
            printf("received:%s\n", data.some_data);
        }else{
            perror("open client fifo to read failed");
            exit(EXIT_FAILURE);
        }
    
        close(cli_fifo_fd);
        close(serv_fifo_fd);
        exit(EXIT_SUCCESS);
    }
    

    result


  3. 信號(hào)量,有時(shí)使用信號(hào)量完成進(jìn)程或線程同步
    了解四個(gè)信號(hào)量操作函數(shù)
    sem_init\sem_post\sem_wait\sem_destroy
    example

    #include<stdio.h>
    #include<stdlib.h>
    #include<semaphore.h>
    #include<string.h>
    #include<pthread.h>
    char work_area[1024];
    sem_t semaphore;
    void* thread_func(void* arg){
        sem_wait(&semaphore);
        while(strncmp(work_area, "end", 3) != 0){
            printf("len:%d\n", strlen(work_area) - 1);
            sem_wait(&semaphore);
        }
        pthread_exit(EXIT_SUCCESS);
    }
    int main(){
        int res;
        pthread_t thread;
        void* thread_res;
        res = sem_init(&semaphore, 0, 0);
        if(res != 0){
            perror("初始化信號(hào)量失敵入宦!");
            exit(EXIT_FAILURE);
        }
        if((res = pthread_create(&thread, NULL, thread_func, NULL)) != 0){
            perror("線程創(chuàng)建失敗");
            exit(EXIT_FAILURE);
        }
        printf("please input a string:\n");
        while(strncmp(work_area, "end", 3) != 0){
            fgets(work_area, 1024, stdin);
            sem_post(&semaphore);
        }
        printf("wait for the thread exit!\n");
        if((res = pthread_join(thread, &thread_res)) != 0){
            perror("等待線程結(jié)束出錯(cuò)!");
            exit(EXIT_FAILURE);
        }
        printf("線程已退出室琢!\n");
        sem_destroy(&semaphore);
        exit(EXIT_SUCCESS);
    }
    
  4. 共享內(nèi)存
    顧名思義乾闰,就是一塊兩者都可以訪問(wèn)的內(nèi)存,進(jìn)程通過(guò)原子性的寫(xiě)入操作保證數(shù)據(jù)完整性盈滴。
    要點(diǎn):理解創(chuàng)建與操作共享內(nèi)存的系統(tǒng)調(diào)用涯肩,使用manual



    看一個(gè)服務(wù)進(jìn)程與客戶進(jìn)程的例子
    server.c

        #include"common.h"
    int main(){
        int running = 1;
        void *share_mem;
        struct share_mem_st *data;
        int shmid;
        char buf[50];
    
        shmid = shmget((key_t)1234, sizeof(struct share_mem_st), 0666 | IPC_CREAT);
        if(shmid == -1){
            perror("create share_memory failed");
            exit(EXIT_FAILURE);
        }
    
        share_mem = shmat(shmid, (void*)0, 0);
        if(share_mem == (void*)-1){
            perror("attach the mem failed");
            exit(EXIT_FAILURE);
        }
        printf("share memory attached at %X\n", share_mem);
        
        data = (struct share_mem_st*)share_mem;
        data->controller = 0;
        while(running){
            while(data->controller == 1){
                printf("wait for client...\n");
                sleep(1);
            }
            puts("type the message:");
            //fgets(buf, 50, stdin);
            memset(buf, '\0', 50);
            scanf("%s", buf);
            memset(data->message, '\0', TEXT_SIZE);
            strncpy(data->message, buf, strlen(buf));
            data->controller = 1;
            if(strncmp(buf, "end", 3) == 0){
                running = 0;
            }
            
        }
    
        printf("exiting...\n");
        if(shmdt(share_mem) == -1){
            perror("error between unttach the share_meme");
            exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
    }
    

    client.c

    #include"common.h"
    int main(){
        int shmid;
        struct share_mem_st* data;
        void* share_mem;
        int running = 1;
        char buf[50];
    
        if((shmid = shmget((key_t)1234, sizeof(struct share_mem_st), 0666 | IPC_CREAT)) == -1){
            perror("create share mem failed");
            exit(EXIT_FAILURE);
        }
    
        if((share_mem = shmat(shmid, (void*)0, 0)) == (void*)-1){
            perror("attach the share mem failed");
            exit(EXIT_FAILURE);
        }
        printf("share mem attach at %X\n", share_mem);
        data = (struct share_mem_st*)share_mem;
        data->controller = 1;
        while(running){
            if(data->controller == 1){
                strncpy(buf, data->message, strlen(data->message));
                printf("message:%s\n", buf);
                sleep(2);
                data->controller = 0;
                if(strncmp(buf, "end", 3) == 0){
                    running = 0;
                }
            }else{
                printf("waiting for server...\n");
                sleep(1);
            }
        }
        if(shmdt(share_mem) == -1){
            perror("unattach the share mem failed");
            exit(EXIT_FAILURE);
        }
        if(shmctl(shmid, IPC_RMID, 0) == -1){
            perror("error with release the share mem");
            exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
    
    }
    
  5. 消息隊(duì)列
    隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),用于進(jìn)程間通信時(shí)較為靈活巢钓,可以設(shè)計(jì)為分布式病苗,十分適合與網(wǎng)絡(luò)應(yīng)用進(jìn)程通信,爬蟲(chóng)程序就是一個(gè)很好的例子
    首先需要理解創(chuàng)建和使用消息隊(duì)列的一些系統(tǒng)調(diào)用-manual



    一個(gè)使用消息隊(duì)列相互通信的例子
    common.h

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<string.h>
    #include<errno.h>
    
    #include<sys/types.h>
    #include<sys/ipc.h>
    #include<sys/msg.h>
    
    #define BUF_SIZE 1024
    struct msg_st{
        long int msg_type;
        char data[BUF_SIZE];
    };
    

    server.c

    #include"common.h"
    int main(){
        int running = 1;
        struct msg_st msg_data;
        int msg_id;
        long int msg_type_receive = 1;
    
        if((msg_id = msgget((key_t)1234, 0666| IPC_CREAT)) == -1){
            perror("server:can't create message queue");
            exit(EXIT_FAILURE);
        }
        printf("get message queue with id:%d\n", msg_id);
    
        while(running){
            if(msgrcv(msg_id, (void*)&msg_data, BUF_SIZE, msg_type_receive, 0) == -1){
                perror("recv data from queue failed");
                exit(EXIT_FAILURE);
            }
            printf("you wrote:%s\n", msg_data.data);
            if(strncmp(msg_data.data, "end", 3) == 0){
                printf("exiting...\n");
                running = 0;
    
            }
        }
        msgctl(msg_id, IPC_RMID, 0);
        exit(EXIT_SUCCESS);
    }
    

    client.c

    #include"common.h"
    int main(){
        int running = 1;
        struct msg_st msg_data;
        long int msg_type_receive = 0;
        char buf[BUF_SIZE];
        int msg_id;
    
        if((msg_id = msgget((key_t)1234, 0666 | IPC_CREAT)) == -1){
            perror("client:get message queue failed");
            exit(EXIT_FAILURE);
        }
        printf("get message queue with id:%d\n", msg_id);
        int length = 0;
        while(running){
            memset(msg_data.data, '\0', BUF_SIZE);
            printf("input some text:");
            fgets(buf, BUFSIZ, stdin);
            length = strlen(buf);
            msg_data.msg_type = 1;
            strncpy(msg_data.data, buf, length -1);
            msg_data.data[length] = '\0';
            if(msgsnd(msg_id, (void*)&msg_data, BUF_SIZE, 0) == -1){
                perror("error with send data");
                exit(EXIT_FAILURE);
            }
            printf("you send:%s\n", msg_data.data);
            if(strncmp(buf, "end", 3) == 0){
                printf("exiting...\n");
                running = 0;
            }
        }
    
        exit(EXIT_SUCCESS);
    
    }
    

    client



    server


  6. 總結(jié)
    信號(hào)症汹、管道硫朦、命名管道、共享內(nèi)存背镇、消息隊(duì)列以及信號(hào)量是進(jìn)程間通信的重要手段咬展,我們需要了解他們分別適用于何種情形花履,優(yōu)缺點(diǎn),如何使用挚赊,如何處理錯(cuò)誤诡壁,碰到不記得的函數(shù)用法,可以通過(guò)manual查看該函數(shù)聲明荠割,數(shù)據(jù)結(jié)構(gòu)等等信息妹卿。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蔑鹦,隨后出現(xiàn)的幾起案子夺克,更是在濱河造成了極大的恐慌,老刑警劉巖嚎朽,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铺纽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡哟忍,警方通過(guò)查閱死者的電腦和手機(jī)狡门,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)锅很,“玉大人其馏,你說(shuō)我怎么就攤上這事”玻” “怎么了叛复?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)扔仓。 經(jīng)常有香客問(wèn)我褐奥,道長(zhǎng),這世上最難降的妖魔是什么翘簇? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任撬码,我火速辦了婚禮,結(jié)果婚禮上缘揪,老公的妹妹穿的比我還像新娘耍群。我一直安慰自己,他們只是感情好找筝,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布蹈垢。 她就那樣靜靜地躺著,像睡著了一般袖裕。 火紅的嫁衣襯著肌膚如雪曹抬。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,837評(píng)論 1 290
  • 那天急鳄,我揣著相機(jī)與錄音谤民,去河邊找鬼堰酿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛张足,可吹牛的內(nèi)容都是我干的触创。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼为牍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼哼绑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起碉咆,我...
    開(kāi)封第一講書(shū)人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤抖韩,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后疫铜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體茂浮,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年壳咕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了席揽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡囱井,死狀恐怖驹尼,靈堂內(nèi)的尸體忽然破棺而出趣避,到底是詐尸還是另有隱情庞呕,我是刑警寧澤,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布程帕,位于F島的核電站住练,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏愁拭。R本人自食惡果不足惜讲逛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望岭埠。 院中可真熱鬧盏混,春花似錦、人聲如沸惜论。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)馆类。三九已至混聊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乾巧,已是汗流浹背句喜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工预愤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留使套,地道東北人盒齿。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓峡扩,卻偏偏與公主長(zhǎng)得像均驶,于是被迫代替她去往敵國(guó)和親登馒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拣播,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

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