Linux - 管道

No.1 进程间通信的八种方式

    1. 普通文件
      两个进程访问同一个文件 有先后顺序
    1. 文件映射虚拟内存
      父子进程之间
    1. 管道
    1. 信号
    1. IPC之 共享内存
    1. IPC之 消息队列
    1. IPC之 消息量(旗语)
    1. 网络通信

No.2 文件映射虚拟内存通讯

    1. 创建文件
    1. 文件映射成虚拟内存在fork之前
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <time.h>
/*
    父进程      持续不断滚动输出
    子进程      持续不断等待用户输入
                按下空格键 停止滚动 再按以下恢复滚动
*/
//文件映射虚拟内存
int main()
{
    //1. 创建文件
    int fd = open("mmap.dat",O_CREAT|O_RDWR,0777);
    
    ftruncate(fd,4);

    //2. 文件映射成虚拟内存在fork之前
    int*p = (int*)mmap(NULL,4,PROT_READ|PROT_WRITE,
            MAP_SHARED,fd,0);
    *p = 0;
    if(fork())//父进程
    {
        srand(time(NULL));
        while(1)
        {
            while(*p);//开关
            usleep(1000); //10ms
            printf("%08d\n",rand()%100000000);
           
        }
    }
    else//子进程
    {
        char ch;
        while(1)
        {
            read(0,&ch,1);
            if('\n'== ch)//回车停止输出
                if( 0==*p) *p = 1;
                else *p=0;
        }
    }
}

No.3 管道(同一主机之上用得比较多)

  • 管道:管道是一个文件 (FIFO First In First Out)以文件形式存在的一个特殊队列

  • 匿名管道:没有名字
    专门用于父子之间,直接使用文件描述符号,
    不需要文件名
    fd[0] 用来读
    fd[1] 用来写
    //1 创建两个文件描述符号 (两个int整形)
    int fd[2];
    //2 把文件描述符号变成管道
    pipe
    //3 使用管道进行通信

    //4 关闭
    close(fd[0]);
    close(fd[1]);

#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main()
{
    //1 创建两个文件描述符号 (两个int整形)
	int fd[2];
    //2 把文件描述符号变成管道
	pipe(fd);
    //3 使用管道进行通信
    if(fork())
    {
        char temp[1024];
        int r;
        while(1)
        {
            r = read(fd[0],temp,1023);
            if(r>0)
            {
                temp[r] = 0;//添加结束符号
                printf(">> %s\n",temp);//打印数据
            }
        }
    }
    else
    {
        char temp[1024];
        while(1)
        {
            memset(temp,0,1024);
            printf("你要发送点啥:");
            scanf("%s",temp);
            write(fd[1],temp,strlen(temp));
        }
    }
	//4 关闭
	close(fd[0]);
	close(fd[1]); 
}

在这里插入图片描述

#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main()
{
    //1 创建两个文件描述符号 (两个int整形)
	int fd[2];
    //2 把文件描述符号变成管道
	pipe(fd);
    //3 使用管道进行通信
    if(fork())
    {
        char temp[1024];
        int r;
        while(1)
        {
            r = read(fd[0],temp,1023);
            if(r>0)
            {
                temp[r] = 0;//添加结束符号
                printf(">> %s\n",temp);//打印数据
            }
        }
    }
#if 0
    else
    {
        char temp[1024];
        while(1)
        {
            memset(temp,0,1024);
            printf("你要发送点啥:");
            scanf("%s",temp);
            write(fd[1],temp,strlen(temp));
        }
    }
#else
else
    {
        char temp[1024];
        int r=0;
        while(1)
        {
            sprintf(temp,"hahahahah:%d\n",r++);
            write(fd[1],temp,strlen(temp));
            sleep(1);
        }
    }
#endif
	//4 关闭
	close(fd[0]);
	close(fd[1]); 
}

在这里插入图片描述

  • 有名管道:有名字

可以在同一主机上不同进程之间操作 有具体的文件

		A												B
//1. 创建管道文件(mkfifo)		
//2. 打开管道文件					//1. 打开管道文件
		open
//3. 使用管道文件(读)			//2. 使用管道文件(写)
		read write
//4. 关闭									//3. 关闭
		close
//5. 删除管道文件
		unlink

管道一边打开后阻塞 等待另外一边打开 结束open函数
A

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{

    //1. 创建管道文件(mkfifo)	
    int r = mkfifo("test.pipe",0777);
    if(0==r) printf("创建管道文件:%m\n");
    else printf("创建管道文件失败:%m\n"),exit(-1);	
	//2. 打开管道文件					
	int fd = open("test.pipe",O_WRONLY);
    if(-1==fd) printf("打开管道文件失败:%m\n"),exit(-1);
    else printf("打开管道文件成功:%m\n");	
	//3. 使用管道文件(写)			
    int n;
    char buff[56];
    int d=0;
    while(5>d)
    {
        sprintf(buff,"hahahaha:%d",d++);
        write(fd,buff,strlen(buff));
        sleep(1);
    }
	//4. 关闭								
	close(fd);
	//5. 删除管道文件
	unlink("test.pipe");
    return 0;
}

B

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
    	
	//1. 打开管道文件
    int fd = open("test.pipe",O_RDONLY);
    if(-1==fd) printf("打开管道文件失败:%m\n"),exit(-1);
    else printf("打开管道文件成功:%m\n");	
	//2. 使用管道文件(读)
    char buff[56];
    int r;
    while(1)
    {   
        memset(buff,0,56);
        
        r = read(fd,buff,55);
        if(r>0)
        {
            buff[r] = 0;
            printf(">> %s\n",buff);
        }
    }		
	//3. 关闭
	close(fd);

    return 0;
}

在这里插入图片描述
在这里插入图片描述

Copy on write(写时拷贝)
只有当需要写的时候才拷贝,只进行读操作,不进行拷贝。
子进程拷贝父进程所有代码
父进程中有个int n;
当后面的程序没有改n的值的时候,操作系统中只有一份n,只有当要修改n的值的时候,才进行拷贝.

传输文件文件到Test目录下

A

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
int main(int argc,char* argv[])
{

    if(argc!=2) return 0;

    //1. 创建管道文件(mkfifo)	
    int r = mkfifo("test.pipe",0777);
    if(0==r) printf("创建管道文件:%m\n");
    else printf("创建管道文件失败:%m\n"),exit(-1);	
	//2. 打开管道文件					
	int fd = open("test.pipe",O_WRONLY);
    if(-1==fd) printf("打开管道文件失败:%m\n"),exit(-1);
    else printf("打开管道文件成功:%m\n");	
	//3. 使用管道文件(写)	
    //3.1 获取要传输的文件信息		
    struct stat st ; 
    stat(argv[1],&st);
    //3.2 传送文件名长度
    int Size = strlen(argv[1]);
    write(fd,&Size,4);
    //3.3 传送文件名
    write(fd,argv[1],strlen(argv[1]));
    printf("%s %ld\n",argv[1],st.st_size);
    //3.4 传送文件大小
    Size = st.st_size;
    write(fd,&Size,sizeof Size);
    //3.5 打开文件然后传送文件
    int fw = open(argv[1],O_RDONLY);
    r=0;
    char c;
    while(1)
    {
        r = read(fw,&c,1);
        if(r!=1)
        {
            printf("拷贝完成!\n");
            break;
        }
        write(fd,&c,1);
    }
    



	//4. 关闭								
	close(fd);
    close(fw);
	//5. 删除管道文件
	unlink("test.pipe");
    return 0;
}

B

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
    	
	//1. 打开管道文件
    int fd = open("test.pipe",O_RDONLY);
    if(-1==fd) printf("打开管道文件失败:%m\n"),exit(-1);
    else printf("打开管道文件成功:%m\n");	
	//2. 使用管道文件(读)
    //2.1 获取文件名长度
    int r = 0;
    read(fd,&r,4);
    char* name = (char*)malloc((r+1));
    //2.2 获取文件名
    r = read(fd,name,r);
    name[r+1] = 0;
    printf("%s\n",name);
    //2.3 获取文件内容长度
    int Size;
    read(fd,&Size,4);
    printf("size:%d\n",Size);
    //2.4 创建文件夹Test
    system("mkdir Test");
    //2.5 链接文件目录
    char demo[1024];
    sprintf(demo,"./Test/%s",name);
    printf("%s\n",demo);
    //2.6 创建文件并且进行接受
    int fw = open(demo,O_WRONLY|O_CREAT,0666);
    int n=0;
    char c;
    while(n<=Size)
    {   
        read(fd,&c,1);
        n++;
        write(fw,&c,1);
    }		
	//3. 关闭
	close(fd);
    close(fw);

    return 0;
}

执行结果
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux是一种操作系统,而-bash是Linux中的一种shell(命令行解释器),它允许用户在命令行中输入命令并执行它们。-bash是Linux默认的shell之一,它提供了许多有用的功能和命令,使用户能够更轻松地管理和操作系统。 ### 回答2: Linux -bash 是指 Linux 系统中的 Bash(Bourne Again SHell)终端或命令行界面。 Bash 是一种常用的 Unix shell,它是用于管理和执行命令行操作的基础工具。它允许用户在 Linux 系统上输入和执行各种命令,与系统进行交互,并管理文件文件夹。 Linux -bash 提供了一个交互式环境,用户可以在其中执行各种命令。它可以用于执行系统管理任务,如安装软件包、配置网络设置、管理用户和权限等。此外,还可以使用 bash 脚本编批量处理任务,实现自动化和脚本化操作。 在 -bash 终端中,用户可以使用各种命令来探索文件系统、浏览文件文件夹、编辑文本文件等。用户可以通过输入命令和参数,实现不同的操作和功能,比如复制、移动、删除文件,修改文件权限等等。 -bash 终端也提供了强大的命令行编辑和历史纪录功能。用户可以使用上下箭头键浏览之前输入的命令,并进行修改和再次执行。此外,可以使用 Tab 键进行自动完成操作,节省输入命令的时间和工作量。 总而言之,Linux -bash 是 Linux 系统中常用的命令行界面,在系统管理、文件操作和批处理方面提供了丰富的功能和灵活性,是 Linux 用户和系统管理员必不可少的工具之一。 ### 回答3: Linux的-bash是一种命令行解释器,也称为Bourne Again SHell。Bash是Unix操作系统中最常用的shell之一,由于Linux是基于UNIX的,因此Bash也成为了Linux中最常用的shell。 -bash表示当前用户所使用的shell环境是Bash。在Linux系统中,当我们打开终端或者SSH登录到服务器时,会自动进入一个shell环境,这个环境中我们可以使用各种命令来执行各种操作。 Bash是一个功能强大且灵活的shell,它支持大量的命令,可以用于管理和操作文件、目录、进程、权限、网络等各个方面。通过Bash,我们可以输入命令并执行,也可以编shell脚本来进行自动化操作。 在-bash下,我们可以使用各种命令来管理Linux系统,比如ls命令用于列出当前目录下的文件和子目录,cd命令用于切换目录,pwd命令用于显示当前所在的目录,mkdir命令用于创建新的目录,rm命令用于删除文件和目录,等等。 此外,Bash还支持各种运算符和控制结构,允许我们编复杂的shell脚本来自动化任务。我们可以使用if语句来进行条件判断,使用for和while循环来进行重复操作,还可以通过管道(|)来连接多个命令,实现更复杂的操作。 总之,Linux的-bash是一种强大的命令行解释器,它为我们提供了丰富的命令和功能,使我们能够高效地管理和操作Linux系统。无论是日常使用还是系统管理,熟练掌握-bash都是非常重要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值