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

news2025/2/25 1:01:55

文章目录

  • 一、实验目的
  • 二、实验内容
  • 三、实验要求
  • 四、实验步骤及操作
  • 五、程序源码
    • 1. 普通管道 piperw.c
    • 2. 无名管道 wrfifo.c
    • 3. 有名管道 rdfifo.c


一、实验目的

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

二、实验内容

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

三、实验要求

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

四、实验步骤及操作

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

五、程序源码

1. 普通管道 piperw.c

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>

#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);
}

在这里插入图片描述

2. 无名管道 wrfifo.c

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <time.h>

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);
}

在这里插入图片描述

3. 有名管道 rdfifo.c

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>

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);
}


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/40566.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

day13_面向对象的三大特征之一(封装)

封装概述 为什么需要封装&#xff1f; 现实生活中&#xff0c;每一个个体与个体之间是有边界的&#xff0c;每一个团体与团体之间是有边界的&#xff0c;而同一个个体、团体内部的信息是互通的&#xff0c;只是对外有所隐瞒。例如&#xff1a;我们使用的电脑&#xff0c;内部…

Java框架篇(来自硅谷的面试题)

目录 一 简单的谈一下SpringMVC的工作流程&#xff1f; 二 说出Spring或者SpringMVC中常用的5个注解&#xff0c;并解释含义 三 简述SpringMVC中如何返回JSON数据&#xff08;北京&#xff09; 四 谈谈你对Spring的理解 五 Spring中常用的设计模式 六 Spring循环…

IDA安装使用

最近学逆向&#xff0c;先备一套工具吧&#xff0c;IDA名声在外&#xff0c;首当其冲&#xff01;&#xff01; 内容主要整理自别的博客&#xff0c; Linux下安装IDA 链接: https://pan.baidu.com/s/1p9elz1a34872LsY1WLJmlA?pwdis2u 这个ida版本为32bit Linux系统准备的&…

Linux生产者消费者与信号量

目录 一.生产者消费者概念 二.模拟实现基于阻塞队列的生产消费模型 2.1概念 2.2构造阻塞队列 三.信号量 3.1原理 3.2信号量函数 3.3信号量模拟互斥功能 一.生产者消费者概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。 生产者和消费者彼此之间…

【C语言】十六进制转换为十进制

目录 题目描述 补充知识&#xff1a; 算法分析 优化算法 写在最后 题目描述 输入一个十六进制数字串&#xff0c;将其转换成为对应的整数并输出转换结果&#xff0c;遇到非十六进制数字或字符串结束符&#xff08;\0&#xff09;结束转换。 注意&#xff1a; 输入的字符…

【Java多线程】初识线程及三种创建方式

➤ Java多线程编程【一文全解】 文章目录线程简介进程的创建> 继承 Thread 类> 实现 Runnable 接口> 实现 Callable 接口线程简介 普通的程序中&#xff0c;方法的调用是执行到方法的时候&#xff0c;程序跳转到方法体中进行&#xff0c;是按照顺序进行的&#xff0c;…

说说未来趋势 「元宇宙」是什么?

最近「元宇宙」概念大火&#xff0c;连星爷等各行各业的各路大佬都可以传出消息布局进入这一个领域&#xff0c;那么这是不是意味这IT信息化时代的下一个风口&#xff0c;就是元宇宙呢&#xff1f;按小郭说呀&#xff0c;这目前来看&#xff0c;这个趋势是必然的&#xff0c;就…

Spirng 痛苦源码学习(一)——总起spring(一)

文章目录前言一、总览Spring的bean1&#xff09;bean的过程【先了解具体的生命周期后面弄】2&#xff09;hello spring 简单bean操作二、总览AOP- 1、test coding- 2、- debug- 3、- 总结debug三、总览事务- 1、- test coding- 2、 debugging- 3、 事务失效- 4、事务总结前言 …

cpu设计和实现(流水线暂停)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说过&#xff0c;数字电路里面流水线的引入&#xff0c;主要是为了提高数据的处理效率。那么&#xff0c;鉴于此&#xff0c;为什么又要对…

ssm宠物商城管理系统源码

在 Internet飞速开展的今天&#xff0c;互联网成为人们快速获取、发布和传 递信息的重要渠道&#xff0c;它在人们学习、工作、生活等各个方面发挥着重要的作用。 因此建立在 Internet应用上的地位显而易见&#xff0c;它已成为政府、企事业单位信息化 建立中的重要组成局部&am…

[附源码]SSM计算机毕业设计网上书店管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【kafka】十五、kafka消费者API

kafka消费者API Consumer消费数据时的可靠性是很容易保证的&#xff0c;因为数据在kafka中是持久化的&#xff0c;故不用担心数据丢失的问题。 由于consumer在消费过程中可能会出现断电宕机的等故障&#xff0c;consumer恢复后&#xff0c;需要从故障前的位置继续消费&#xf…

visual studio 2019 + Qt 开发,使用visual leak detector检测内存泄漏

选择了在vs2019上开发Qt, 遇到了内存泄露问题。还好vs上有方便的visual leak detector&#xff08;vld&#xff09;检测工具。 虽然官网上只支持到vs2015, 但vs2019上也能用。 具体参考这位博主的文章&#xff1a;https://blog.csdn.net/qq_22108657/article/details/1208843…

Redis数据库安装(Windows)

目录 一、下载Windows安装包 二、启动Redis 1.在终端中启动 2.使用start.bat文件启动 3.添加服务启动 三、安装Redis可视化管理工具 1.安装Redis图形客户端 2.连接数据库 一、下载Windows安装包 下载地址&#xff1a;Releases tporadowski/redis GitHub 选择下载相…

单链表的递归详解 (leetcode习题+ C++实现)

文章目录合并两个有序链表翻转链表链表中移除节点合并两个有序链表 传送门&#xff1a; https://leetcode.cn/problems/merge-two-sorted-lists/description/ 题目要求&#xff1b; 给你两个有序的链表&#xff0c;将这两个链表按照从小到大的关系&#xff0c;合并两个链表为…

Mybatis快速入门

Mybatis安装与配置 Mybatis概述 Mybatis本质上是一个别人写好的框架&#xff0c;用于简化 JDBC 开发&#xff0c;通过Mybatis框架&#xff0c;可以极大的降低JDBC的开发难度。 官方文档&#xff1a;https://mybatis.org/mybatis-3/zh/index.html Mybatis快速入门 需求&…

MySQL进阶实战10,MySQL全文索引

一、全文索引 全文索引的目的是 通过关键字的匹配进行查询过滤&#xff0c;基于相似度的查询&#xff0c;而不是精确查询。 全文索引利用分词技术分析出文字中某关键字的频率和重要性&#xff0c;并按照一定的算法智能的筛选出我们想要的结果。 全文索引一般用于字符串中某关…

tomcat服务器安装及配置教程(保姆级教程)

Tomcat安装教程 &#xff08;以tomcat-9.0.62为例&#xff1a;&#xff09; 1.下载安装包 可以从官网下载安装包&#xff1a; &#xff08;1&#xff09;从官网下载 输入网址进入官网 选择版本10&#xff0c;版本9&#xff0c;或者版本8&#xff0c;都可以&#xff0c;这里…

掘金热榜首推!阿里内部都在用的Java后端面试笔记,囊括99%的主流技术

纵观今年的技术招聘市场&#xff0c; Java依旧是当仁不让的霸主 &#xff01;即便遭受 Go等新兴语言不断冲击&#xff0c;依旧岿然不动。究其原因&#xff1a; Java有着极其成熟的生态&#xff0c;这个不用我多说&#xff1b;Java在 运维、可观测性、可监 控性方面都有着非常优…

Spring Boot JPA 本机查询示例

在本教程中&#xff0c;您将了解如何在 Spring 引导中使用 Spring Data JPA 本机查询示例&#xff08;带参数&#xff09;。我将向您展示&#xff1a; 将 Spring JPA 本机查询与Query注释一起使用的方法如何在 Spring 引导中执行 SQL 查询具有 WHERE 条件的 JPA 选择查询示例 …