系统编程-文件操作5

作业

  1. 通过无名管道,让两个子进程间完成相互通信工作
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/wait.h>

int main()
{
    int pipefd[2]={0};
    int ret=-1;
    ret=pipe(pipefd);
    if(-1==ret)
    {
        perror("pipe");
        return -1;
    }
    pid_t pid=fork();
    if(pid>0)
    {
        pid_t pid2=fork();
        if(pid2>0)
        {
            waitpid(pid,NULL,0);
            waitpid(pid2,NULL,0);
        }
        else if(0==pid2)
        {
            int iSign=0;
            char caBuf[64]={'\0'};
            while(1)
            {
                memset(caBuf,'\0',sizeof(caBuf));
                if(0==iSign)
                {
                    printf("child1-input data:");
                    scanf("%s",caBuf);
                    write(pipefd[1],caBuf,strlen(caBuf));
                    iSign=1;
                }
                else if(1==iSign)
                {
                    read(pipefd[0],caBuf,sizeof(caBuf));
                    printf("child2 says:%s\n",caBuf);
                    iSign=0;
                }
                sleep(1);
            }
        }
        else if(-1==pid2)
        {
            perror("second fork");
            return -1;
        }
    }
    else if(0==pid)
    {
        int iSign=0;
        char caBuf[64]={'\0'};
        while(1)
        {
            memset(caBuf,'\0',sizeof(caBuf));
            if(0==iSign)
            {
                read(pipefd[0],caBuf,sizeof(caBuf));
                printf("child1 says:%s\n", caBuf);
                iSign=1;
            }
            else if(1==iSign)
            {
                printf("child2-input data:");
                scanf("%s",caBuf);
                write(pipefd[1],caBuf,strlen(caBuf));
                iSign=0;
            }
            sleep(1);
        }
    }
    else if(-1==pid)
    {
        perror("first fork");
        return -1;
    }

}

Paste_Image.png
Paste_Image.png

命名管道

  • 创建一个命名管道
#include<sys/types.h>
#include<sys/stat.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#define FIFO_PATHNAME "myFifo"
int main(void)
{
    int ret=-1;
    ret=mkfifo(FIFO_PATHNAME,0777);
    if(-1==ret)
    {
        if(EEXIST!=errno)//如果错误等于这个已经存在,我们可以直接运行
        {
            perror("mkfifo");
            exit(EXIT_FAILURE);
        }
    }
    printf("mkfifo is ok\n");

    return 0;
}

Paste_Image.png
  • 在命名管道里插入数据
  1. 首先在一个终端运行写
 #include<sys/types.h>
 #include<sys/stat.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define FIFO_PATHNAME "myFifo"
int main(void)
{
    int ret=-1;
    ret=mkfifo(FIFO_PATHNAME,0777);//创建一个管道文件
    if(-1==ret)
    {
        if(EEXIST!=errno)//如果错误等于这个已经存在,我们可以直接运行
        {
            perror("mkfifo");
            exit(EXIT_FAILURE);
        }
    }
    printf("mkfifo is ok\n");
    int fd=-1;
    fd=open(FIFO_PATHNAME,O_WRONLY);
    if(-1==fd)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }
    ret=write(fd,"hello world",11);//没有另一端进行读,所以一直阻塞在那里,直到有读的把他打开
    if(ret>0)
    {
        printf("write %d bytes to fifo\n",ret);
    }
    close(fd);
    return 0;
}


  • 在另外一个终端运行读的程序(这样写的程序才不会阻塞)

 #include<sys/types.h>
 #include<sys/stat.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define FIFO_PATHNAME "myFifo"
int main(void)
{
    int ret=-1;
    ret=mkfifo(FIFO_PATHNAME,0777);//创建一个管道文件
    if(-1==ret)
    {
        if(EEXIST!=errno)//如果错误等于这个已经存在,我们可以直接运行
        {
            perror("mkfifo");
            exit(EXIT_FAILURE);
        }
    }
    printf("mkfifo is ok\n");
    int fd=-1;
    fd=open(FIFO_PATHNAME,O_RDONLY);
    if(-1==fd)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }
    char caBuf[64]={'\0'};
    ret=read(fd,caBuf,sizeof(caBuf));//没有另一端进行读,所以一直阻塞在那里,直到有读的把他打开
    if(ret>0)
    {
        printf("%s\n",caBuf);
        printf("read %d bytes from fifo\n",ret);
    }
    close(fd);
    return 0;
}


  • 管道中的数据,读取了之后,就已经没有数据了
  • 管道两端相互通信
 #include<sys/types.h>
 #include<sys/stat.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FIFO_PATHNAME "myFifo"
int main(void)
{
    int ret=-1;
    ret=mkfifo(FIFO_PATHNAME,0777);//创建一个管道文件
    if(-1==ret)
    {
        if(EEXIST!=errno)//如果错误等于这个已经存在,我们可以直接运行
        {
            perror("mkfifo");
            exit(EXIT_FAILURE);
        }
    }
    printf("mkfifo is ok\n");
    int fd=-1;
    fd=open(FIFO_PATHNAME,O_RDWR);
    if(-1==fd)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }
    int iSign=0;
    char caBuf[64]={'\0'};
    while(1)
    {
        memset(caBuf, '\0', sizeof(caBuf));
        if(iSign==0)
        {
            printf("1.please iput data\n");
            
            scanf("%s",caBuf);
            ret=write(fd,caBuf,strlen(caBuf));//没有另一端进行读,所以一直阻塞在那里,直到有读的把他打开
            if(ret==-1)
            {
                perror("write");
                exit(EXIT_FAILURE);
            }
            iSign=1;
            sleep(1);
        }
        else if(iSign==1)
        {
            ret=read(fd,caBuf,sizeof(caBuf));//没有另一端进行读,所以一直阻塞在那里,直到有读的把他打开
            if(ret==-1)
            {
                perror("read");
                exit(EXIT_FAILURE);
            }   
            printf("1.receive data:%s\n",caBuf);
            iSign=0;
        }
    }
    close(fd);
    return 0;
}


 #include<sys/types.h>
 #include<sys/stat.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FIFO_PATHNAME "myFifo"
int main(void)
{
    int ret=-1;
    ret=mkfifo(FIFO_PATHNAME,0777);//创建一个管道文件
    if(-1==ret)
    {
        if(EEXIST!=errno)//如果错误等于这个已经存在,我们可以直接运行
        {
            perror("mkfifo");
            exit(EXIT_FAILURE);
        }
    }
    printf("mkfifo is ok\n");
    int fd=-1;
    fd=open(FIFO_PATHNAME,O_RDWR);
    if(-1==fd)
    {
        perror("open");
        exit(EXIT_FAILURE);
    }
    int iSign=0;
    char caBuf[64]={'\0'};
    while(1)
    {
        memset(caBuf, '\0', sizeof(caBuf));
        if(iSign==0)
        {
            printf("1.please iput data\n");
            
            scanf("%s",caBuf);
            ret=write(fd,caBuf,strlen(caBuf));//没有另一端进行读,所以一直阻塞在那里,直到有读的把他打开
            if(ret==-1)
            {
                perror("write");
                exit(EXIT_FAILURE);
            }
            iSign=1;
            sleep(1);
        }
        else if(iSign==1)
        {
            ret=read(fd,caBuf,sizeof(caBuf));//没有另一端进行读,所以一直阻塞在那里,直到有读的把他打开
            if(ret==-1)
            {
                perror("read");
                exit(EXIT_FAILURE);
            }   
            printf("1.receive data:%s\n",caBuf);
            iSign=0;
        }
    }
    close(fd);
    return 0;
}


Paste_Image.png

总结管道的特点(只能在父子进程中使用)

  1. 单向通信
  2. 公共祖先

另一种通信方式(共享内存块)//shmget

  • IPC:进程间的通信
#include <sys/ipc.h>
#include <sys/shm.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
    int shmid=-1;
    //第一个参数:key_t key,相当于这块共享内存块的名字
    //第二个参数:这个共享内存块的大小
    shmid=shmget(0x1117,1024,IPC_CREAT);//它是十六进制的数据
    if(-1==shmid)
    {
        perror("shmget");
        exit(EXIT_FAILURE);
    }
    printf("shmget ok:%d\n",shmid);
    return 0;
}

Paste_Image.png
Paste_Image.png
Paste_Image.png
  • 通过这种方法,则不用输入sudo ipcs -m,只需输入 ipcs -m就可以了,因为在程序中已经设置了他的权限
#include <sys/ipc.h>
#include <sys/shm.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
    int shmid=-1;
    //第一个参数:key_t key,相当于这块共享内存块的名字
    //第二个参数:这个共享内存块的大小
    shmid=shmget(0x1204,1024,IPC_CREAT | S_IRUSR | S_IWUSR);//它是十六进制的数据
    if(-1==shmid)
    {
        perror("shmget");
        exit(EXIT_FAILURE);
    }
    printf("shmget ok:%d\n",shmid);
    return 0;
}

Paste_Image.png
Paste_Image.png

shmop

  • 创建一个共享内存块,再往里面插入数据,>再显
  • 插入数据
#include <sys/ipc.h>
#include <sys/shm.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
    int shmid=-1;
    //第一个参数:key_t key,相当于这块共享内存块的名字
    //第二个参数:这个共享内存块的大小
    shmid=shmget(0x1204,1024,IPC_CREAT | S_IRUSR | S_IWUSR);//它是十六进制的数据
    if(-1==shmid)
    {
        perror("shmget");
        exit(EXIT_FAILURE);
    }
    printf("shmget ok:id=%d\n",shmid);
    void *pRet=NULL;
    pRet=shmat(shmid,NULL,0);//只读打开或者读写打开为0,没有只写打开
    if((void *)-1==pRet)//(void *)-1就是返回值的类型,表示错误的话返回这个
    {
        perror("shmat");
        exit(EXIT_FAILURE);
    }
    char *pData="I want to sleep";
    memcpy(pRet,pData,strlen(pData));//复制指指针变量

    shmdt(pRet);//斩断与内存块的关联
    return 0;
}

Paste_Image.png
  • 读取数据
#include <sys/ipc.h>
#include <sys/shm.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
    int shmid=-1;
    //第一个参数:key_t key,相当于这块共享内存块的名字
    //第二个参数:这个共享内存块的大小
    shmid=shmget(0x1204,1024,IPC_CREAT | S_IRUSR | S_IWUSR);//它是十六进制的数据
    if(-1==shmid)
    {
        perror("shmget");
        exit(EXIT_FAILURE);
    }
    printf("shmget ok:id=%d\n",shmid);
    void *pRet=NULL;
    pRet=shmat(shmid,NULL,SHM_RDONLY);//只读打开或者读写打开为0,没有只写打开
    if((void *)-1==pRet)//(void *)-1就是返回值的类型,表示错误的话返回这个
    {
        perror("shmat");
        exit(EXIT_FAILURE);
    }
    char caBuf[32]={'\0'};
    memset(caBuf,'\0',sizeof(caBuf));//最好初始化一下,以免存在野值
    memcpy(caBuf,pRet,sizeof(caBuf));
    printf("%s\n",caBuf);
    shmdt(pRet);//斩断与内存块的关联
    return 0;
}

Paste_Image.png

shmctl 控制共享内存(要最后释放掉共享内存,则用)

#include <sys/ipc.h>
#include <sys/shm.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(void)
{
    int shmid=-1;
    //第一个参数:key_t key,相当于这块共享内存块的名字
    //第二个参数:这个共享内存块的大小
    shmid=shmget(0x1204,1024,IPC_CREAT | S_IRUSR | S_IWUSR);//它是十六进制的数据
    if(-1==shmid)
    {
        perror("shmget");
        exit(EXIT_FAILURE);
    }
    printf("shmget ok:id=%d\n",shmid);
    void *pRet=NULL;
    pRet=shmat(shmid,NULL,SHM_RDONLY);//只读打开或者读写打开为0,没有只写打开
    if((void *)-1==pRet)//(void *)-1就是返回值的类型,表示错误的话返回这个
    {
        perror("shmat");
        exit(EXIT_FAILURE);
    }
    char caBuf[32]={'\0'};
    memset(caBuf,'\0',sizeof(caBuf));//最好初始化一下,以免存在野值
    //数据读取之后,仍然保留在共享内存里面
    //直到下一次写数据的时候被覆盖
    memcpy(caBuf,pRet,sizeof(caBuf));
    printf("%s\n",caBuf);

    struct shmid_ds shmInfo;
    //控制共享内存
    //IPC_STAT:获得共享内存的信息,
    shmctl(shmid,IPC_STAT,&shmInfo);
    printf("shm size= %ld\n",shmInfo.shm_segsz);
    shmctl(shmid,IPC_RMID,0);//消除内存空间
    //shmdt(pRet);//斩断与内存块的关联
    return 0;
}

  • ipcrm +编号(删除某个内存);
  • 将共享内存块映射到进程里

第三种通信方式 mmap(创建一个进程映射到虚拟地址)

  • 将数据写入到这块内存空间
#include <sys/ipc.h>
#include <sys/mman.h>//mmap()
#include <sys/shm.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
    int fd=-1;
    fd=open("test",O_RDWR);//"test"表示当前目录,
    if(-1==fd)
    {
        perror("open");
        exit(-1);
    }
    void *pRet=NULL;
    pRet=mmap(NULL,32,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);//SHARED:其他进程也可以访问,10,偏移量
    if((void *)-1==pRet)
    {
        perror("mmap");
        exit(-1);
    }
    sprintf((char *)pRet,"%s %d %f\n","huihuidashadan",1024,3.14);//与memcpy一样,复制指针,即字符串//将数据格式化的写到这块内存空间里去
    munmap(pRet,32);//取消映射

    return 0;
}

//在test里面插入数据
//运行结果:插入到了test中,如果test里没有数据的话,就会报总线错误(核心已转储)


Paste_Image.png
  • 将数据读取出来
#include <sys/ipc.h>
#include <sys/mman.h>//mmap()
#include <sys/shm.h>

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
    int fd=-1;
    fd=open("test",O_RDWR);//"test"表示当前目录,
    if(-1==fd)
    {
        perror("open");
        exit(-1);
    }
    void *pRet=NULL;
    pRet=mmap(NULL,32,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0);//SHARED:其他进程也可以访问,10,偏移量
    if((void *)-1==pRet)
    {
        perror("mmap");
        exit(-1);
    }
    sprintf((char *)pRet,"%s %d %f\n","huihuidashadan",1024,3.14);//与memcpy一样,复制指针,即字符串//将数据格式化的写到这块内存空间里去
    char caBuf[32]={'\0'};
    int iData=0;
    float fData=0;
    sscanf(pRet,"%s%d%f",caBuf,&iData,&fData);//格式化输入数据
    printf("%s %d %.2f\n",caBuf,iData,fData);
    munmap(pRet,32);//取消映射
    close(fd);
    return 0;
}

//


Paste_Image.png

第四种通信方式 (signal):信号

  • A将信号传到内存里,B进程通过信号处理函数处理信号

信号的产生(硬件产生信号,软件产生信号)

  • kill(),产生信号
/*kill()*/
#include<sys/types.h>
#include<signal.h>

/*fork()*/
#include<unistd.h>

#include<stdio.h>
#include<stdlib.h>
int main(void)
{
    pid_t pid=-1;
    pid=fork();
    if(pid>0)
    {
        while(1)
        {
            printf("I am parent,waiting child to kill me\n");
            sleep(1);
        }
    }
    else if(pid==0)
    {
        int i=5;
        while(1)
        {
            if(0==i)
            {
                printf("i kill parent\n");
                kill(getppid(),SIGKILL);//getppid()h获得父进程的进程号
                break;
            }
            else
            {
                printf("still has %d second to kill parent\n",i);
                sleep(1);
            }
            i--;
        }
    }
    else if(pid==-1)
    {
        perror("fork");
        exit(-1);
    }
}


Paste_Image.png
  • 发送一个闹钟信号(alarm信号默认自杀)
#include<stdio.h>
#include<stdlib.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
    //在指定的秒数之后,给本进程发送一个SIGALRM信号,该信号的默认处理是结束进程
    alarm(5);
    while(1)
    {
        printf("huihuidashabi\n");
        sleep(1);
    }
    return 0;
}

Paste_Image.png

raise,一个信号产生

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
int main()
{
    int i=5;
    while(1)
    {
        if(i==0)
        {
            raise(SIGKILL);
        }
        printf("ZZZZzzzzz~~~\n");
        i--;
        sleep(1);
    }
}

Paste_Image.png

自定义信号处理

  • kill与stop不能以我们自定义的信号处理方式处理
#include<signal.h>//signal()
#include<stdio.h>
#include<string.h>
typedef void (*sighandler_t)(int);

void sigHandle(int sig)
{
    if(SIGALRM==sig)
    {
        printf("catched sigalrm\n");
    }
}
int main(void)
{
    sighandler_t ret;
    //指定信号的处理方式
    //第一个参数:需要处理特殊处理的信号
    //第二个参数:信号的处理方式
    ret=signal(SIGALRM,sigHandle);
    if(SIG_ERR==ret)
    {
        printf("signal failed\n");
        return -1;
    }
    alarm(3);
    while(1)
    {
    }
    return 0;
}

Paste_Image.png
  • 设置一个信号,Ctrl+c,按下Ctrl+c,z则捕捉到信息
#include<signal.h>//signal()
#include<stdio.h>
#include<string.h>
typedef void (*sighandler_t)(int);
//使用SigHandle
void sigHandle(int sig)
{
    if(SIGALRM==sig)
    {
        printf("catched sigalrm\n");
    }
    else if(SIGINT==sig)
    {
        printf("catched signal\n");
    }
}
int main(void)
{
    
    sighandler_t ret;
    //指定信号的处理方式
    //第一个参数:需要处理特殊处理的信号
    //第二个参数:信号的处理方式
    ret=signal(SIGALRM,sigHandle);
    if(SIG_ERR==ret)
    {
        printf("signal failed\n");
        return -1;
    }
    //SIG_DFL:使用该信号的默认处理动作来处理该信号
    //SIG_IGN:忽略该信号
    ret=signal(SIGINT,sigHandle)
    if(SIG_ERR==ret)
    {
        printf("signal failed\n");
        return -1;
    }
    alarm(3);
    while(1)
    {
    }   
    return 0;
}

//按Ctrl+\键退出运行

Paste_Image.png
#include<signal.h>//signal()
#include<stdio.h>
#include<string.h>
typedef void (*sighandler_t)(int);
//使用SigHandle
void sigHandle(int sig)
{
    if(SIGALRM==sig)
    {
        printf("catched sigalrm\n");
    }
    else if(SIGINT==sig)
    {
        printf("catched signal\n");
    }
}
int main(void)
{
    
    sighandler_t ret;
    //指定信号的处理方式
    //第一个参数:需要处理特殊处理的信号
    //第二个参数:信号的处理方式
    ret=signal(SIGALRM,sigHandle);
    if(SIG_ERR==ret)
    {
        printf("signal failed\n");
        return -1;
    }
    //SIG_DFL:使用该信号的默认处理动作来处理该信号
    //SIG_IGN:忽略该信号
    ret=signal(SIGINT,SIG_IGN);
    if(SIG_ERR==ret)
    {
        printf("signal failed\n");
        return -1;
    }
    alarm(3);
    while(1)
    {
    }   
    return 0;
}

//SIG_IGN:是忽略该信号,所以再按下Ctrl+c已经没有反应了

Paste_Image.png
#include<signal.h>//signal()
#include<stdio.h>
#include<string.h>
typedef void (*sighandler_t)(int);
//使用SigHandle
void sigHandle(int sig)
{
    if(SIGALRM==sig)
    {
        printf("catched sigalrm\n");
    }
    else if(SIGINT==sig)
    {
        printf("catched signal\n");
    }
}
int main(void)
{
    
    sighandler_t ret;
    //指定信号的处理方式
    //第一个参数:需要处理特殊处理的信号
    //第二个参数:信号的处理方式
    ret=signal(SIGALRM,sigHandle);
    if(SIG_ERR==ret)
    {
        printf("signal failed\n");
        return -1;
    }
    //SIG_DFL:使用该信号的默认处理动作来处理该信号
    //SIG_IGN:忽略该信号
    //ret=signal(SIGINT,sigHandle);
    ret=signal(SIGINT,SIG_DFL);
    if(SIG_ERR==ret)
    {
        printf("signal failed\n");
        return -1;
    }
    alarm(3);
    while(1)
    {
    }   
    return 0;
}

//SIG_DFL:使用该信号的默认处理动作来处理该信号

Paste_Image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容