day05

作者: 萌面大叔2 | 来源:发表于2017-02-15 13:06 被阅读0次

    通过无名管道,让两个子进程间完成相互通信工作

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    
    int main(void)
    {
        int pipefd[2] = {0};
        int ret = -1;
        ret = pipe(pipefd);
        if (-1 == ret)
        {
            perror("pipe");
            return -1;
        }
    
        pid_t pid = fork();
        if (pid > 0) //parent
        {
            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("second-input data:");
                        scanf("%s", caBuf);
                        write(pipefd[1], caBuf, strlen(caBuf));
                        iSign = 1;
                    }
                    else if (1 == iSign)
                    {
                        read(pipefd[0], caBuf, sizeof(caBuf));
                        printf("first says:%s\n", caBuf);
                        iSign = 0;
                    }
                    sleep(1);
                }
            }
            else if (-1 == pid2)
            {
                perror("second fork");
                return -1;
            }
        }
        else if (0 == pid) //child
        {
            int iSign = 0;
            char caBuf[64] = {'\0'};
            while (1)
            {
                memset(caBuf, '\0', sizeof(caBuf));
                if (0 == iSign)
                {
                    read(pipefd[0], caBuf, sizeof(caBuf));
                    printf("second says:%s\n", caBuf);
                    iSign = 1;
                }
                else if (1 == iSign)
                {
                    printf("first-input data:");
                    scanf("%s", caBuf);
                    write(pipefd[1], caBuf, strlen(caBuf));
                    iSign = 0;
                }
                sleep(1);
            }
        }
        else if (-1 == pid)  //error
        {
            perror("first fork");
            return -1;
        }
    
        return 0;
    }
    
    

    运行结果:


    捕获.PNG

    命名管道和一般的管道基本相同,区别:
    1,命名管道在文件系统中作为一个特殊的设备文件而存在
    2,不同祖先的进程之间可以通过管道共享数据
    3,当所有使用到管道的进程执行完IO操作后,
    命名管道并不会销毁,
    而是继续保存在文件系统中以便后面使用


    fifo.png

    chat_fifo.c(chat_fifo.c和2chat_fifo.c通信)

    /*mkfifo(): a named pipe*/
    #include <sys/types.h>
    #include <sys/stat.h>
    /*open()*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <stdio.h>
    #include <string.h> //perror()   strerror()
    #include <errno.h>  //errno
    #include <stdlib.h>
    #include <unistd.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("fifo 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[32] = {'\0'};
        while (1)
        {
            memset(caBuf, '\0', sizeof(caBuf));
            if (0 == iSign)
            {
                printf("1,please input data:");
                scanf("%s", caBuf);
                ret = write(fd, caBuf, strlen(caBuf));
                if (-1 == ret)
                {
                    perror("write");
                    exit(EXIT_FAILURE);
                }
                iSign = 1;
                sleep(1);
            }
            else if (1 == iSign)
            {
                ret = read(fd, caBuf, sizeof(caBuf));
                if (-1 == ret)
                {
                    perror("read");
                    exit(EXIT_FAILURE);
                }
                printf("1,receive data: %s\n", caBuf);
                iSign = 0;
            }
        }
        close(fd);
    
        return 0;
    }
    
    

    2chat_fifo.c

    /*mkfifo(): a named pipe*/
    #include <sys/types.h>
    #include <sys/stat.h>
    /*open()*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <stdio.h>
    #include <string.h> //perror()   strerror()
    #include <errno.h>  //errno
    #include <stdlib.h>
    #include <unistd.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("fifo 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[32] = {'\0'};
        while (1)
        {
            memset(caBuf, '\0', sizeof(caBuf));
            if (0 == iSign)
            {
                ret = read(fd, caBuf, sizeof(caBuf));
                if (-1 == ret)
                {
                    perror("read");
                    exit(EXIT_FAILURE);
                }
                printf("2,receive data: %s\n", caBuf);
                iSign = 1;
            }
            else if (1 == iSign)
            {
                printf("2,please input data:");
                scanf("%s", caBuf);
                ret = write(fd, caBuf, strlen(caBuf));
                if (-1 == ret)
                {
                    perror("write");
                    exit(EXIT_FAILURE);
                }
                iSign = 0;
                sleep(1);
            }
        }
        close(fd);
    
        return 0;
    }
    

    运行结果:


    chat_fifo.c(先写).PNG 2chat_fifo.c(先读).PNG

    writ_fifo.c

    /*mkfifo(): a named pipe*/
    #include <sys/types.h>
    #include <sys/stat.h>
    /*open()*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <stdio.h>
    #include <string.h> //perror()   strerror()
    #include <errno.h>  //errno
    #include <stdlib.h>
    #include <unistd.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("fifo 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;
    }
    

    运行结果:


    write_fifo.PNG

    read_fifo.c

    
    /*mkfifo(): a named pipe*/
    #include <sys/types.h>
    #include <sys/stat.h>
    /*open()*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <stdio.h>
    #include <string.h> //perror()   strerror()
    #include <errno.h>  //errno
    #include <stdlib.h>
    #include <unistd.h>
    
    #define FIFO_PATHNAME "myFifo"
    
    int main(void)
    {
        int ret = -1;
        //创建命名管道:
        //第一个参数:管道的路径名
        //第二个参数:操作管道的权限
        ret = mkfifo(FIFO_PATHNAME, 0777);
        //创建管道成功返回0,失败返回-1
        if (-1 == ret)
        {
            if (EEXIST != errno)
            {
                perror("mkfifo");
                exit(EXIT_FAILURE);
            }
        }
        printf("fifo is ok\n");
        //管道创建成功后,可以像普通文件一样操作
        //open,read,write,close
        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;
    }
    
    

    运行结果:

    read_fifo.PNG

    test.c

    /*mkfifo(): a named pipe*/
    #include <sys/types.h>
    #include <sys/stat.h>
    /*open()*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    #include <stdio.h>
    #include <string.h> //perror()   strerror()
    #include <errno.h>  //errno
    #include <stdlib.h>
    #include <unistd.h>
    
    #define FIFO_PATHNAME "fifo.txt"
    
    int main(void)
    {
        int ret = -1;
        //创建命名管道:
        //第一个参数:管道的路径名
        //第二个参数:操作管道的权限
        ret = mkfifo(FIFO_PATHNAME, 0777);
        //创建管道成功返回0,失败返回-1
        if (-1 == ret)
        {
            if (EEXIST != errno)
            {
                perror("mkfifo");
                exit(EXIT_FAILURE);
            }
        }
        printf("fifo is ok\n");
        //管道创建成功后,可以像普通文件一样操作
        //open,read,write,close
        int fd = -1;
        fd = open(FIFO_PATHNAME, O_RDONLY);
        if (-1 == fd)
        {
            perror("open");
            exit(EXIT_FAILURE);
        }
    while (1)
    {
        char caBuf[64] = {'\0'};
        ret = read(fd, caBuf, sizeof(caBuf));
        if (0 == ret)
        {
            printf("no data to read\n");
            sleep(1);
            //break;
        }
        if (ret > 0)
        {
            printf("%s\n", caBuf);
            printf("read %d bytes from fifo\n", ret);
        }
    }
        close(fd);
    
        return 0;
    }
    

    运行结果:


    test.PNG

    mmap.c

    #include <sys/mman.h>   //mmap
    #include <stdio.h>
    #include <string.h>
    /*open()*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    /*close()*/
    #include <unistd.h>
    #include <stdlib.h> //exit()
    
    int main(void)
    {
        int fd = -1;
        fd = open("test", O_RDWR);
        if (-1 == fd)
        {
            perror("open");
            exit(-1);
        }
    
        void *pRet = NULL;
        pRet = mmap(NULL, 32, PROT_WRITE | PROT_READ, MAP_SHARED
                    , fd, 0);
        if ((void *)-1 == pRet)
        {
            perror("mmap");
            exit(-1);
        }
        //memcpy();
        sprintf((char *)pRet, "%s %d %.2f\n"
                , "laoshaotongchi", 1024, 3.14);
    
        munmap(pRet, 32);
    
        return 0;
    }
    
    

    read.c

    #include <sys/mman.h>   //mmap
    #include <stdio.h>
    #include <string.h>
    /*open()*/
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    /*close()*/
    #include <unistd.h>
    #include <stdlib.h> //exit()
    
    int main(void)
    {
        int fd = -1;
        fd = open("test", O_RDWR);
        if (-1 == fd)
        {
            perror("open");
            exit(-1);
        }
    
        void *pRet = NULL;
        pRet = mmap(NULL, 32, PROT_WRITE | PROT_READ, MAP_SHARED
                    , fd, 0);
        if ((void *)-1 == pRet)
        {
            perror("mmap");
            exit(-1);
        }
        //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;
    }
    

    运行结果:


    mmap.PNG

    pipe

    pipe1.png pipe2.png

    shmget.c

    /*shmget()*/
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #include <stdio.h>
    #include <errno.h>  //errno
    #include <string.h> //perror()
    #include <unistd.h>
    #include <stdlib.h>  //exit()
    
    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);
        if ((void *)-1 == pRet)
        {
            perror("shmat");
            exit(EXIT_FAILURE);
        }
        char *pData = "I want to sleep";
        memcpy(pRet, pData, strlen(pData));
    
        shmdt(pRet);
    
        return 0;
    }
    
    

    运行结果:


    shmget.PNG

    readShm.c

    /*shmget()*/
    #include <sys/ipc.h>
    #include <sys/shm.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    
    #include <stdio.h>
    #include <errno.h>  //errno
    #include <string.h> //perror()
    #include <unistd.h>
    #include <stdlib.h>  //exit()
    
    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;
        //将共享内存映射到进程空间
        //第二个参数:表示映射到进程空间哪个地方
        //    NULL: 表示让系统自动映射到进程空间合适的地方去
        //第三个参数:指定对共享内存的操作权限
        //    SHM_RDONLY:只读
        //    0:读写
        //    没有只写
        pRet = shmat(shmid, NULL, SHM_RDONLY);
        if ((void *)-1 == pRet)
        {
            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:获得共享内存的信息,将信息放在shmInfo中
        shmctl(shmid, IPC_STAT, &shmInfo);
        printf("shm size = %d\n", shmInfo.shm_segsz);
        
        shmctl(shmid, IPC_RMID, NULL);
    
        //shmdt(pRet);
    
        return 0;
    }
    
    

    alarm.c

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(void)
    {
        //在指定的秒数之后,给本进程发送一个SIGALRM信号
        //该信号的默认处理是结束进程
    
        //如果参数seconds为0,
        //则之前设置的闹钟会被取消,并将剩下的时间返回
    
        //返回值:如果调用此alarm()前,
        //进程已经设置了闹钟时间,
        //则返回上一个闹钟时间的剩余时间,否则返回0。 
        //出错返回-1
        alarm(5);
        while (1)
        {
            printf("hahahahahahaha...\n");
            sleep(1);
        }
    
        return 0;
    }
    

    运行结果:


    alarm.PNG

    kill.c

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

    运行结果:


    kill.PNG

    raise.c

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

    运行结果:

    raise.PNG

    signal.c

    #include <signal.h>  //signal()
    #include <stdio.h>
    #include <string.h>
    
    typedef void (*sighandler_t)(int);
    //使用sigHandle函数处理信号时
    //会将信号的值赋给形参sig
    void sigHandle(int sig)
    {
        if (SIGALRM == sig)
        {
            printf("catched sigalrm\n");
        }
        else if (SIGINT == sig)
        {
            printf("catched sigint\n");
        }
        //SIGINT //ctrl + c
    }
    
    int main(void)
    {
        //The  signals  SIGKILL  and SIGSTOP cannot be caught or ignored.
        sighandler_t ret;
        //指定信号的处理方式
        //第一个参数:需要特殊处理的信号
        //第二个参数:信号的处理方式
        ret = signal(SIGALRM, sigHandle);
        if (SIG_ERR == ret)
        {
            printf("signal failed\n");
            return -1;
        }
    //  ret = signal(SIGINT, sigHandle);
        //SIG_DFL:使用该信号的默认处理动作来处理该信号
    //  ret = signal(SIGINT, 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;
    }
    

    运行结果:

    signal.PNG

    相关文章

      网友评论

          本文标题:day05

          本文链接:https://www.haomeiwen.com/subject/nlklmttx.html