Linux管道——进程间通信(匿名管道、命名管道)

news2024/11/19 21:17:45

文章目录

  • 一、进程间通信
    • 1.1 进程间通信的概念
    • 1.2 进程间通信的目的
    • 1.3 进程间通信的本质
    • 1.4 进程间通信的分类
  • 二、管道
    • 2.1 匿名管道
      • ① 匿名管道的使用场景
      • ② 匿名管道实现通信的原理
      • ③ 创建匿名管道 pipe函数
      • ④ fork共享管道
      • ⑤ 匿名管道的五个特点
      • ⑥ 匿名管道的四种特殊情况
    • 2.2 命名管道
      • ① 命名管道的原理
      • ② 命名管道的FIFO文件和一般文件有什么区别
      • ③ 使用命令创建命名管道
      • ④ 使用接口创建一个命名管道
  • 三、小节
  • 四、相关题目

一、进程间通信

1.1 进程间通信的概念

进程之间可能会存在特定的协同工作的场景!

一个进程要把自己的数据交付给另一个进程,让其进行处理-》进程间通信

由于进程具有独立性,一个进程看不到另一个进程的资源!所以交互数据的成本一定很高,这时就需要操作系统参与设计通信方式。两个进程要互相通信,就要能看到一份公共的资源,这里的资源就是一段内存!这个公共资源属于操作系统!

进程间通信简称IPC(Interprocess communication),进程间通信就是在不同进程之间传播或交换信息。

1.2 进程间通信的目的

  • 数据传输: 一个进程需要将它的数据发送给另一个进程。
  • 资源共享: 多个进程之间共享同样的资源。
  • 通知事件: 一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件,比如进程终止时需要通知其父进程。
  • 进程控制: 有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

1.3 进程间通信的本质

进程间通信的本质:其实就是由OS参与,提供一份所有通信进程都能看到的公共资源。

这段内存可能以文件的方式提供,也可能以队列的方式提供,也可能是原始的内存块。-》这也是通信方式有很多种的原因

由于各个运行进程之间具有独立性,这个独立性主要体现在数据层面,而代码逻辑层面可以私有也可以公有(例如父子进程),因此各个进程之间要实现通信是非常困难的。

各个进程之间若想实现通信,一定要借助第三方资源,这些进程就可以通过向这个第三方资源写入或是读取数据,进而实现进程之间的通信,这个第三方资源实际上就是操作系统提供的一段内存区域。
在这里插入图片描述
因此,进程间通信的本质就是,让不同的进程看到同一份资源(内存,文件内核缓冲等)。 由于这份资源可以由操作系统中的不同模块提供,因此出现了不同的进程间通信方式。

1.4 进程间通信的分类

管道

  • 匿名管道
  • 命名管道

System V IPC

  • System V 消息队列
  • System V 共享内存
  • System V 信号量

POSIX IPC

  • 消息队列
  • 共享内存
  • 信号量
  • 互斥量
  • 条件变量
  • 读写锁

本文主要介绍管道

二、管道

管道本身是一个文件。用管道实现进程间的通信,实际上是通过文件来实现进程间的通信。

管道又分为匿名管道和命名管道,顾名思义,匿名管道,创建的管道名字是不知道的,命名管道,创建管道的名字是知道的。

注意:管道实现通信只能进程单向通信。一个进程读,一个进程写。

2.1 匿名管道

① 匿名管道的使用场景

匿名管道通常使用于有亲缘关系的进程之间,常用于父子进程。看完原理再来理解一下这句话。

有亲缘关系的进程,会继承同一个祖先进程的部分内容。其中files_struct是继承祖先进程的。可以使两亲缘关系的进程指向同一文件。

所以为什么子进程会默认打开stdin,stdout,stderr,但是子进程并没有执行open操作?

只需要祖先进程打开了stdin,stdout,stderr就好了,子进程会拷贝父进程内容。

image-20221011144610830

write做了两件事:把数据从用户缓冲区拷贝到内核缓冲区,触发底层硬件的写入函数,写进磁盘文件。父进程往缓冲区里写入,如果缓冲区里的数据没有写入文件,这时子进程就能读取到缓冲区里的数据,达成通信,这就是管道

注意:

  • 这里父子进程看到的同一份文件资源是由操作系统来维护的,这个文件不属于任何一个进程,所以当父子进程对该文件进行写入操作时,该文件缓冲区当中的数据并不会进行写时拷贝。
  • 管道虽然用的是文件的方案,但操作系统一定不会把进程进行通信的数据刷新到磁盘当中,因为这样做有IO参与会降低效率,而且也没有必要。也就是说,这种文件是一批不会把数据写到磁盘当中的文件,换句话说,磁盘文件和内存文件不一定是一一对应的,有些文件只会在内存当中存在,而不会在磁盘当中存在。

② 匿名管道实现通信的原理

  • 管道也是一个文件,站在文件的角度来理解管道实现通信的原理。

​ 管道是一个文件,当一个进程以读和写的方式打开一个管道再创建一个子进程,子进程会以父进程为模板,拷贝父进程的部分内容。此时file_strcut里的数组(文件描述符与文件的映射关系)会是父进程的拷贝。此时,父子进程都指向了管道文件(同一块空间),并且子进程也是以读写方式打开的该文件(因为子进程会继承父进程代码,父进程在创建子进程之前以读写方式打开的文件),如果一个进程对文件进行写,一个进程对文件进行读,由于两个进程指向同一空间,所以读进程拿到的数据就是写进程写进去的数据。此时就完成了对文件的通信。

image-20221011144308097

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bpZEIw9g-1673141600698)(null)]

③ 创建匿名管道 pipe函数

pipe函数用于创建匿名管道,pip函数的函数原型,功能:创建匿名管道

int pipe(int pipefd[2]);

pipe函数的参数是一个输出型参数,数组pipefd用于返回两个指向管道读端和写端的文件描述符:

数组元素含义
pipefd[0]管道读端的文件描述符
pipefd[1]管道写端的文件描述符

pipe函数调用成功时返回0,调用失败时返回-1,并设置错误码。

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(){
    int fd[2] = {0};        
    //以读写方式打开管道
    int res = pipe(fd);
    if(res == 0){
        printf("fd[0]:%d,fd[1]:%d\n",fd[0],fd[1]);//打印:fd[0]:3,fd[1]:4	
        // 文件描述符fd:0 1 2 被标准输入 标准输出 标准错误 占据
    }
    else{
        perror("pipe error");
        exit(1);
    }
    return 0;
}

④ fork共享管道

原理
不同的进程,要用同一个匿名管道进行通信,则需要进程拥有该管道的读写两端的文件描述符,所以匿名管道只让能具有亲缘关系的进程进行进程间通信,且父进程需要先创建匿名管道,再创建子进程。如图所示:

image-20221011145938892

上图中管道在内核空间,而父子进程的程序都在用户空间中。可以令子进程进行写,父进程进行读,关闭各自不用的文件描述符,仍可以进行单向通信。

image-20221011150052237

程序

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include <fcntl.h>
int main()
{
    int pipefd[2] = {0};
    //父进程需要读写两端都打开,否则子进程继承下去就只有一个端口。
    if(pipe(pipefd)!=0){
        perror("pipe");
        return 1;
    }
    int id = fork();
    if(id > 0)//父进程
    {
        //parent写入
        close(pipefd[0]);//关闭父进程的pipe读端
        const char* msg = "i am father";
        while(1)
        {
            sleep(1);
            write(pipefd[1],msg,strlen(msg));
        }
        printf("father quit...\n");
        return 0;
    }
    else if(id == 0)//子进程
    {
        //child读取
        close(pipefd[1]);//关闭子进程的pipe写端
        char buff[64] = {0};
        while(1)
        {
            sleep(1);
            ssize_t s = read(pipefd[0], buff, sizeof(buff)-1);

            if(s>0)
            {
                buff[s] = 0;//C语言里字符串以0表示结束
                printf("i am child,i read:%s\n",buff);
            }
            else if(s==0)
            {
                break;
            }
            else
            {
                break;
            }
        }
    }
    else{
        //error
    }

    return 0;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Mv9uLhQh-1673141600673)(null)]

⑤ 匿名管道的五个特点

**① 管道内部自带同步与互斥机制 ** 👈

我们将一次只允许一个进程使用的资源,称为临界资源。管道在同一时刻只允许一个进程对其进行写入或是读取操作,因此管道也就是一种临界资源。

临界资源是需要被保护的,若是我们不对管道这种临界资源进行任何保护机制,那么就可能出现同一时刻有多个进程对同一管道进行操作的情况,进而导致同时读写、交叉读写以及读取到的数据不一致等问题。

为了避免这些问题,内核会对管道操作进行同步与互斥:

  • 同步: 两个或两个以上的进程在运行过程中协同步调,按预定的先后次序运行。比如,A任务的运行依赖于B任务产生的数据。
  • 互斥: 一个公共资源同一时刻只能被一个进程使用,多个进程不能同时使用公共资源。

实际上,同步是一种更为复杂的互斥,而互斥是一种特殊的同步。对于管道的场景来说,互斥就是两个进程不可以同时对管道进行操作,它们会相互排斥,必须等一个进程操作完毕,另一个才能操作,而同步也是指这两个不能同时对管道进行操作,但这两个进程必须要按照某种次序来对管道进行操作。

也就是说,互斥具有唯一性和排它性,但互斥并不限制任务的运行顺序,而同步的任务之间则有明确的顺序关系。

**② 管道的生命周期随进程 **👈

管道本质上是通过文件进行通信的,也就是说管道依赖于文件系统,那么当所有打开该文件的进程都退出后,该文件也就会被释放掉,所以说管道的生命周期随进程。

如果一个文件只被当前进程打开,相关进程退出了(会自动递减struct file的ref引用计数),被打开的文件会被操作系统自动关闭(ref为0)

③ 管道提供的是流式服务 👈

对于进程A写入管道当中的数据,进程B每次从管道读取的数据的多少是任意的,这种被称为流式服务,与之相对应的是数据报服务:

  • 流式服务: 数据没有明确的分割,不分一定的报文段。
  • 数据报服务: 数据有明确的分割,拿数据按报文段拿。

④ 仅限于父子通信 👈

具有血缘关系的进程之间可以进行通信,常用于父子间通信

⑤ 管道是半双工通信的 👈

在数据通信中,数据在线路上的传送方式可以分为以下三种:

  1. 单工通信(Simplex Communication):单工模式的数据传输是单向的。通信双方中,一方固定为发送端,另一方固定为接收端。
  2. 半双工通信(Half Duplex):半双工数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。
  3. 全双工通信(Full Duplex):全双工通信允许数据在两个方向上同时传输,它的能力相当于两个单工通信方式的结合。全双工可以同时(瞬时)进行信号的双向传输。

管道是半双工的,数据只能向一个方向流动(单向通信),需要双方通信时,需要建立起两个管道。

⑥ 匿名管道的四种特殊情况

在使用管道时,可能出现以下四种特殊情况:

  1. 写端进程不写,读端进程一直读,那么此时会因为管道里面没有数据可读,对应的读端进程会被挂起,直到管道里面有数据后,读端进程才会被唤醒。
  2. 读端进程不读,写端进程一直写,那么当管道被写满后,对应的写端进程会被挂起,直到管道当中的数据被读端进程读取后,写端进程才会被唤醒。
  3. 如果写端关闭了,读端读完pipe内部的数据然后再读,会读到0,表明读到文件结尾。
  4. 读端关闭,写端还在写入,此时OS会直接终止写入进程。如果父进程是读端,父进程能waitpid得到子进程的退出信号,父进程会收到SIGPIPE信号,13号信号。

前面两种情况就能够很好的说明,管道是自带同步与互斥机制的,读端进程和写端进程是有一个步调协调的过程的,不会说当管道没有数据了读端还在读取,而当管道已经满了写端还在写入。读端进程读取数据的条件是管道里面有数据,写端进程写入数据的条件是管道当中还有空间,若是条件不满足,则相应的进程就会被挂起,直到条件满足后才会被再次唤醒。

第三种情况也很好理解,读端进程已经将管道当中的所有数据都读取出来了,而且此后也不会有写端再进行写入了,那么此时读端进程也就可以执行该进程的其他逻辑了,而不会被挂起。

第四种情况也不难理解,既然管道当中的数据已经没有进程会读取了,那么写端进程的写入将没有意义,因此操作系统直接将写端进程杀掉。而此时子进程代码都还没跑完就被终止了,属于异常退出,那么子进程必然收到了某种信号。

2.2 命名管道

为了解决匿名管道只能父子通信的问题,引入了命名管道

① 命名管道的原理

先创建一个命名管道一个进程以读或者写的方式来打开该管道文件,另外一个进程不需要创建管道,只需要以写或者读的方式来打开管道文件。再调用读写系统调用来往文件写或者读,来进行进程间通信。

② 命名管道的FIFO文件和一般文件有什么区别

先说匿名管道的缺点,匿名管道无法让两个没有关系的进程通信。原因在于他是基于内存的,其他进程没有办法找到这块内存,也就没有办法通信了。那么命名管道的意义就在于,他有了名字,有了名字,每个进程就能找到他,也就可以完成通信了。具体的实现来说,命名管道的文件不是用来承载数据的,而且用来做地址用的,为了让每个进程都能通过这个地址进入通信的大门,假设他对应的文件名是a,进程1打开a的时候,拿到一个fd,file,inode,操作系统判断这个文件类型,知道是命名管道文件,会给他分配一块内存,这时候你操作这个文件的时候,数据是写到内存里的,同理,这时候进程2也打开这个文件,也拿到一个fd,file,inode。但是一个文件只有一个inode。所以他们操作的是同一个inode,那就意味着他们操作的是同一块内存,这样就可以通信了。最后,两个进程通过一个一般文件通信当然也是可以的。但是会涉及到硬盘的操作,效率自然就会低

我们通常用 路径+文件名 标识一个磁盘文件,它们具有唯一性。

A,B两个进程如何看到并打开同一个文件的?先将文件数据打开到内存当中,如:写数据时不刷新到磁盘中,数据临时保存在内存,然后两个进程就能通过 路径+文件名 看到同一份资源。

管道的生命周期随进程,本质是内核中的缓冲区,命名管道文件只是标识,用于让多个进程找到同一块缓冲区,删除后,之前已经打开管道的进程依然可以通信

命名管道和匿名管道一样,都是内存文件,只不过命名管道在磁盘有一个简单的映像,但这个映像的大小永远为0,因为命名管道和匿名管道都不会将通信数据刷新到磁盘当中。

③ 使用命令创建命名管道

我们可以使用mkfifo命令创建一个命名管道。

image-20221011153252597

可以看到,创建出来的文件的类型是p,代表该文件是命名管道文件。

简单使用这个命名管道:

在这里插入图片描述

④ 使用接口创建一个命名管道

在程序中创建命名管道使用mkfifo函数,mkfifo函数的函数原型如下:

int mkfifo(const char *pathname, mode_t mode);//在man的3号手册

参数

mkfifo函数的第一个参数是pathname,表示要创建的命名管道文件。

  • 若pathname以路径的方式给出,则将命名管道文件创建在pathname路径下。
  • 若pathname以文件名的方式给出,则将命名管道文件默认创建在当前路径下。(注意当前路径的含义)

mkfifo函数的第二个参数是mode,表示创建命名管道文件的默认权限。

将mode设置为0666,则命名管道文件创建出来的权限如下:
在这里插入图片描述
但实际上创建出来文件的权限值还会受到umask(文件默认掩码)的影响,实际创建出来文件的权限为:mode&(~umask)。umask的默认值一般为0002,当我们设置mode值为0666时实际创建出来文件的权限为0664。
在这里插入图片描述

若想创建出来命名管道文件的权限值不受umask的影响,则需要在创建文件前使用umask函数将文件默认掩码设置为0。

umask(0); //将文件默认掩码设置为0

返回值

  • 命名管道创建成功,返回0。
  • 命名管道创建失败,返回-1。

代码演示

我们在一个进程(serve进程)中创建管道文件并从中读取数据,在另一个进程(client进程)当中每秒向管道文件里面写入一次数据。

client进程运行后,进程serve会每秒从命名管道中读取数据。这就证明了这两个毫不相关的进程可以通过命名管道进行数据传输,即通信。

有了命名管道后,让通信双方进行文件操作即可,推荐使用系统调用接口,库函数接口也可以,但是会有用户缓冲区的一些问题。

在这里插入图片描述

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

共用头文件的代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uTQlzEgA-1673141600715)(null)]

命名管道的数据为了效率,不会刷新到磁盘!

为什么pipe叫匿名管道?因为它是通过父子继承的方式,看到同一份资源不需要名字来标识同一个资源!

为什么fifo叫命名管道?因为命名管道具有名字,这是为了保证不同的进程可以看到同一个文件,所以必须有名字!

三、小节

匿名管道还是命名管道都是通过文件的方式,来让两个进程看到同一份资源。通过一个进程对文件进行写操作,一个文件进程读操作,来实现进程间的通信。

管道实现进程通信是单向的。同步和互斥的。

匿名管道适用于具有血缘关系的进程,命名管道可以用于不相关的进程。

  • 管道本质是内核中的一块缓冲区(命名管道和匿名管道),多个进程通过访问同一块缓冲区实现通信。
  • 使用int pipe(int pipefd[2])接口创建匿名管道,pipefd[0]用于从管道读取数据,pipefd[1]用于向管道写入数据。
  • 管道特性:半双工通信,自带同步与互斥,生命周期随进程,提供字节流传输服务。
  • 在同步的提现中,若管道所有写段关闭,则从管道中读取完所有数据后,继续read会返回0,不再阻塞;若所有读端关闭,则继续write写入会触发异常导致进程退出

​ 理解一个命令:who | wc - l

中间的’|‘是一个匿名管道,who和wc是两个进程,’|'系统通过pipe创建一个匿名管道,bash创建子进程who,bash再创建子进程wc,who和wc是兄弟进程。who和wc都会继承bash的匿名管道文件。who和wc看到统一资源,who往管道写数据,wc从管道读数据。往后数据写完退出,wc读数据到最后也退出了。

四、相关题目

1、以下描述正确的有:

A.进程之间可以直接通过地址访问进行相互通信

B.进程之间不可以直接通过地址访问进行相互通信

C.所有的进程间通信都是通过内核中的缓冲区实现的

D.以上都是错误的

答案解析

A错误: 进程之间具有独立性,拥有自己的虚拟地址空间,因此无法通过各自的虚拟地址进行通信(A的地址经过B的页表映射不一定映射在相同位置)

B正确

C错误: 除了内核中的缓冲区之外还有文件以及网络通信的方式可以实现


2、以下选项属于进程间通信的是()[多选]

A.管道

B.套接字

C.内存

D.消息队列

答案解析

典型进程间通信方式:管道,共享内存,消息队列,信号量。 除此之外还有网络通信,以及文件等多种方式

C选项,这里的内存太过宽泛,并没有特指某种技术,错误。

正确答案是:A,B,D


3、下列关于管道(Pipe)通信的叙述中,正确的是()

A.一个管道可以实现双向数据传输

B.管道的容量仅受磁盘容量大小限制

C.进程对管道进行读操作和写操作都可能被阻塞

D.一个管道只能有一个读进程或一个写进程对其操作

答案解析

A错误 管道是半双工通信,是可以选择方向的单向通信

B错误 管道的本质是内核中的缓冲区,通过内核缓冲区实现通信,命名管道的文件虽然可见于文件系统,但是只是标识符,并非通信介质

C正确 管道自带同步(没有数据读阻塞,缓冲区写满写阻塞)与互斥

D错误 多个进程只要能够访问同一管道就可以实现通信,不限于读写个数


4、以下关于管道的描述中,正确的是 [多选]

A.匿名管道可以用于任意进程间通信

B.匿名管道只能用于具有亲缘关系的进程间通信

C.在创建子进程之后也可以通过创建匿名管道实现父子进程间通信

D.必须在创建子进程之前创建匿名管道才能实现父子进程间通信

答案解析

A错误,匿名管道只能用于具有亲缘关系的进程间通信,命名管道可以用于同一主机上的任意进程间通信

B正确

C错误,匿名管道需要在创建子进程之前创建,因为只有这样才能复制到管道的操作句柄,与具有亲缘关系的进程实现访问同一个管道通信

D正确


5、以下关于管道描述正确的有:

A.命名管道可以用于同一主机上的任意进程间通信

B.向命名管道中写入的数据越多,则管道文件越大

C.若以只读的方式打开命名管道时,则打开操作会报错

D.命名管道可以实现双向通信

答案解析

  • 匿名管道只能用于具有亲缘关系的进程间通信,命名管道可用于同一主机上的任意进程间通信
  • 管道的通信本质是通过内核中一块缓冲区(内存)时间数据传输,而命名管道的管道文件只是一个标识符,用于让多个进程能够访问同一块缓冲区
  • 管道是半双工通信,是可以选择方向的单向通信
  • 命名管道打开特性为,若以只读方式打开文件,则会阻塞,直到管道被以写的方式打开,反之亦然

根据以上理解分析:A选项正确,其他选项错误。

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

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

相关文章

开发模型和测试模型,考点归纳,你都记住了吗?

目录 前言 一、开发模型 1.1、瀑布模型 1.2、螺旋模型 1.3、迭代模型和增量模型 1.4、敏捷模型 敏捷开发最流行的方式——scrum模型 二、测试模型 2.1、V模型 2.2、W模型&#xff08;双V模型&#xff09; 前言 对于模型&#xff0c;需要重点掌握特点&#xff0c;缺点&…

模板编程:constexpr +特例化 判断质数

重点&#xff1a; 1.constexpr 函数支持在编译期间完成计算 2.特例化是模板中一种定义 using namespace std;//编译期进行判断 constexpr bool isPrime(unsigned int p) {for (unsigned int d2;d<p/2;d){if (p % d 0){return false;}}return p > 1; }template<int…

python爬虫入门

基础知识 HTTP协议 我们浏览网页的浏览器和手机应用客户端与服务器通信几乎都是基于HTTP协议&#xff0c;而爬虫可以看作是一个另类的客户端&#xff0c;它把自己伪装成浏览器或者手机应用客户端&#xff0c;按照自己的逻辑贪婪的向服务器索取数据&#xff0c;如何向服务器索…

【实操篇】Linux的网络环境及其配置

目录 ●Linux网络环境原理图&#xff08;NAT模式&#xff09; ●虚拟网络编辑器对虚拟网卡ip进行修改&#xff08;VMnet-&#xff09; ●查看网关( VMnet8->WLAN) ●Linux网络ip配置 1.修改配置文件去获取固定ip 2.自动获取ip连接网络 ●Linux网络环境原理图&#xff…

【vue2】计算属性(computed)与侦听器(watch)详解

&#x1f973;博 主&#xff1a;初映CY的前说(前端领域) &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;计算属性与侦听属性的用法 目录&#xff08;文末有给大家准备好的Xmind思维导图&#xf…

JAVA单商户商城系统源码,前(vue)后(SpringBoot)端分离,支持多平台(h5,小程序,app)

前言 完整代码下载地址&#xff1a;JAVA单商户商城系统源码 linjiashop 是一个基于Spring Boot和Vue.js的web商城系统 linjiashop 包含了商城的后台管理系统,手机h5&#xff0c;小程序版本 linjiashop 采用web-flash作为底层基础框架搭建&#xff0c;开发过程遇到问题请多阅…

Js中闭包的概念和具体使用

前言闭包在js里面是一个比较抽象的概念,但在面试里,是一个必问的话题,往往面试官希望你列举一些使用闭包的例子或手写一个闭包闭包,简单一句话讲就是能够读取其他函数内部变量的函数,当需要函数内容部的变量被外部的代码所访问时那闭包就非常有用了的,如今,很多框架里面的高级特…

Spring整合Mybatis和Junit

文章目录1 Spring整合Mybatis环境搭建整合步骤使用的注解详解2 Spring整合Junit整合Junit步骤使用的注解详解1 Spring整合Mybatis 大体需要做两件事&#xff0c; 第一件事是:Spring要管理MyBatis中的SqlSessionFactory 第二件事是:Spring要管理Mapper接口的扫描 具体该如何实现…

6.Isaac教程--在 C++ 中开发 Codelet

在 C 中开发 Codelet 本教程的目标是用 C 开发两个小码&#xff1a;第一个实际上是一台“ping”的机器&#xff0c;而第二个侦听并摄取“ping”消息。 对于本教程&#xff0c;不需要外部依赖项或特殊硬件。 文章目录在 C 中开发 Codelet创建新应用程序为应用程序创建一个新目录…

【Linux】Linux的基本指令(一)

文章目录1、ls 指令2、pwd 命令3、cd 指令4、touch 指令5、mkdir 指令6、rmdir和rm 指令7、man 指令8、cp 指令9、mv 指令10、cat11、echo(输出&#xff0c;输入&#xff0c;追加重定向)12、wc13、more14、less1、ls 指令 语法&#xff1a; ls[选项][目录或文件] 功能&#xff…

2. 矩阵(matrix)、数组、列表(list)、数据框(data.frame.....)

课程视频链接&#xff1a;https://www.bilibili.com/video/BV19x411X7C6?p1 本笔记参照该视频&#xff0c;笔记顺序做了些调整【个人感觉逻辑顺畅】&#xff0c;并删掉一些不重要的内容 系列笔记目录【持续更新】&#xff1a;https://blog.csdn.net/weixin_42214698/category_…

电脑总是开机黑屏,开机两次才能成功的解决办法:更新BIOS(七彩虹H410M-T PRO)

参考&#xff1a;七彩虹主板更新BIOS的方法 前段时间电脑出问题了&#xff0c;每当我第一次开机都会黑屏&#xff0c;要强制关机第二次开能开机&#xff0c;导致每次都开机很久很久&#xff0c;心情也不好 有时候开机等他一会&#xff0c;大概两分钟&#xff0c;会报如下错误&a…

C++课程成绩管理与分析系统[2023-01-07]

C课程成绩管理与分析系统[2023-01-07] C实习指导书 编写&#xff1a;潘林 修订&#xff1a;邓吉秋 一、实习目的 学生通过此次实习&#xff0c; 应达到如下要求&#xff1a; 熟练使用一种 C开发环境&#xff0c;包括 IDE 与编译器&#xff1b;掌握 C程序的编写 过程与调试&…

Sentinel 是什么

Sentinel是什么 Sentinel 官网&#xff1a;introduction | Sentinel 随着微服务的流行&#xff0c;服务与服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 Sentinel 具有以下特征 丰富…

Rancher部署分布式任务调度系统XXL-JOB通过拉取Docker公共镜像方式

通过Rancher部署分布式任务调度系统XXL-JOB我了解到有两种方式&#xff0c;一种是拉取xxl-job的源代码打包通过Jenkins部署&#xff0c;另一种简单的是直接拉取官方镜像&#xff0c;本文主要讲后面这种。 1、打开Docker公共镜像仓库&#xff0c;搜索xxl-job&#xff0c;复制镜…

GNN笔记系列 3

GNN笔记系列 21.Graph1.1Directed Graphs1.2Symmetric Graphs1.3Unweighted Graphs2.Graph Shift Operators(GSO)2.1Degree Matrix2.2Laplacian Matrix2.3Graph Shift Operator SSS3.Graph Signals4.Graph Convolutional Filters5.Time convolutions and graph convolutions6.G…

itertools包介绍——可以不用 但不能不知道——python包推荐系列

背景1 今天在看一个开源包&#xff0c;发现他的requirements.txt里面放着more_itertools包。 这个包的名字还是挺有意思的&#xff0c;在itertools包前面加上了一个more。难道是python自带的包itertools的加强版&#xff1f; 后来查了一下&#xff0c;这个包&#xff0c;果然…

高并发系统设计的15个锦囊

记得很久之前&#xff0c;去面试过字节跳动。被三面的面试官问了一道场景设计题目&#xff1a;如何设计一个高并发系统。当时我回答得比较粗糙&#xff0c;最近回想起来&#xff0c;所以整理了设计高并发系统的15个锦囊&#xff0c;相信大家看完会有帮助的。 如何理解高并发系统…

【云原生 | 51】Docker三剑客之Docker Compose第二节

&#x1f341;博主简介&#xff1a; &#x1f3c5;云计算领域优质创作者 &#x1f3c5;2022年CSDN新星计划python赛道第一名 &#x1f3c5;2022年CSDN原力计划优质作者 &#x1f3c5;阿里云ACE认证高级工程师 &#x1f3c5;阿里云开发者社区专…

打卡第11天|力扣20. 有效的括号 、 1047. 删除字符串中的所有相邻重复项 、150. 逆波兰表达式求值 。

今天是打卡第十一天&#xff0c;题目主要是栈结构的运用20. 有效的括号题目链接如下&#xff1a;20. 有效的括号我们挨个遍历字符串&#xff0c;每有一个向左的字符串我们就往栈里面存一个向右的括号&#xff0c;遍历到向右的括号时&#xff0c;如果栈中类型相同就弹出&#xf…