• 进程通信(1) ----- 无名管道和有名管道



    一、实验目的

    1.了解操作系统中的无名管道和有名管道
    2.掌握进程通信中的管道编程模型

    二、实验内容

    管道是一种进程间通信的方式,在linux中分为有名管道和无名管道。有名管道就是把一个进程的输出写到一个文件中,再把此文件作为另一个进程的输入,普通管道只能用于父子进程,而有名管道能用于不相关的进程间。本次实验的内容需要编写一个普通管道程序和命名管道程序,并测试。

    三、实验要求

    实验需要提前准备一台PC机,并在PC机上搭建Linux Ubuntu环境。

    四、实验步骤及操作

    1.打开Linux系统,新建一个终端
    2.新建文件
    3.编写代码
    4.编译运行

    五、程序源码

    1. 普通管道 piperw.c

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define BUFSZ PIPE_BUF
    
    void err_quit(char *msg);
    
    int main(int argc, char *argv[])
    {
        int fd[2]; //文件描述符fd[0]表示读取管道,fd[1]表示写入管道
        int fdin; /* 输入文件描述符 */
        char buf[BUFSZ];//buf为缓冲区
        int pid, len;
    
        /* Create the pipe */
        if((pipe(fd)) < 0)
            err_quit("pipe");
        
        /* 分叉并关闭适当的描述符 */
        if((pid = fork()) < 0)
            err_quit("fork");
        if (pid == 0) {
            close(fd[1]);//关闭子进程的写数据
    		//read()函数调用成功会返回读取到的字节数
            while((len = read(fd[0], buf, BUFSZ)) > 0)
    			//STDOUT_FILENO表示将buf中的内容写到标准输出
                write(STDOUT_FILENO, buf, len);//STDIN_FILENO表示标准输出
            close(fd[0]);
        } else {
            /* Parent是writer,关闭读描述符 */
            close(fd[0]);
    		//open函数打开文件成功
            if((fdin = open(argv[1], O_RDONLY)) < 0) {
                perror("open");
                /* 发送一些东西,因为我们无法打开输入 */
                write(fd[1], "123\n", 4);
        	} else {
            //管道里的数据必须被读走
            while((len = read(fdin, buf, BUFSZ)) > 0)
            	write(fd[1], buf, len);
            	close(fdin);
        	}
       		/* 关闭写描述符 */
       		close(fd[1]);
        }
        //waitpid会使目前进程暂停,直到有信号来或者子进程结束
        waitpid(pid, NULL, 0);
        
        
    
        exit(EXIT_SUCCESS);
    }
        
    void err_quit(char *msg)
    {
        perror(msg);
        exit(EXIT_FAILURE);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    在这里插入图片描述

    2. 无名管道 wrfifo.c

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    int main(int argc, char *argv[])
    {
        int fd;			/* FIFO文件描述符 */
      	int len;			/* 写入FIFO的字节 */
        char buf[PIPE_BUF];	/* 确保原子写入 */
        time_t tp;			/* For time call */
    
        /* Identify myself */
        printf("I am %d\n", getpid());
    
        /* Open the FIFO write-only */
        if((fd = open(argv[1], O_WRONLY)) < 0) {
           perror("open");
           exit(EXIT_FAILURE);
        }
    
        /* Generate some data to write */
        while(1) {
            /* 获取当地时间 */
            time(&tp);
            /* 创建要写入的字符串 */
            len = sprintf(buf, "wrfifo %d sends %s", getpid(), ctime(&tp));
            /* 使用(len + 1),因为sprintf不计算结束的null */
            if((write(fd, buf, len + 1)) < 0) {
                perror("write");
                close(fd);
                exit(EXIT_FAILURE);
            }
            printf("%s",buf); 
            sleep(3);
        }
    
        close(fd);
        exit(EXIT_SUCCESS);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    在这里插入图片描述

    3. 有名管道 rdfifo.c

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    void myfunc1(int sign_no)
    {
    	if(sign_no==SIGINT){
    		printf("\nExit pipe!\n");
    	}   
    		
    	else if(sign_no==SIGQUIT)
    		printf("I have get SIGQUIT\n");  
    }
    
    int main(int argc, char *argv[])
    {
    	printf("I am %d\n", getpid());
        int fd;	/* Descriptor for FIFO */
        int len; /* Bytes read from FIFO */
        char buf[PIPE_BUF];
        char buf1[50]="Hello,Bit-Dong!";
    
    	//在当前目录下创建一个有名管道
    	unlink("test_rdfifo");
        if((mkfifo("test_rdfifo",0777)) < 0) {
            perror("mkfifo");
            exit(EXIT_FAILURE);
        }
    
        /* Open the FIFO read-write */
        if((fd = open("test_rdfifo", O_RDWR)) < 0) {
            perror("open");
            exit(EXIT_FAILURE);
        }
        
        if((write(fd,buf1,50))<0){
               perror("write");
       }
        /* 读取并显示FIFO的输出直到EOF */
        	len = read(fd, buf, PIPE_BUF - 1); 
            printf("rdfifo read: %s\n", buf);
        	signal(SIGINT, myfunc1);
       		sleep(10);   
        
    
        close(fd);
    
        exit(EXIT_SUCCESS);
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    在这里插入图片描述

  • 相关阅读:
    C++Qt——信号与槽
    【算法刷题日记之本手篇】二进制插入与查找组成一个偶数最接近的两个素数
    我有 7种 实现web实时消息推送的方案,7种!
    Redis_01_Redis安装与使用
    青少年软件编程C++二级题库(41-50)
    自动化测试:selenium(完结篇)
    iOS iGameGuardian修改器检测方案
    论 shared_ptr的线程安全
    git 重置到某次提交
    Caffeine本地缓存学习
  • 原文地址:https://blog.csdn.net/Dustinthewine/article/details/128068023