操作系统:实验三进程间通信实验

news2024/11/14 18:31:59

一、实验目的

1、了解什么是信号。

2、熟悉LINUX系统中进程之间软中断通信的基本原理。

3、理解进程的同步关系。

4、掌握用信号实现进程间的同步操作。

5、了解什么是管道。

6、熟悉UNIX/LINUX支持的管道通信方式。

、实验内容

1、阅读下列程序,执行程序并给出结果截屏,分析程序功能。(2分)

(1)

#include<unistd.h>

#include<signal.h>

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<sys/wait.h>

int k;

void func()

{   k=0; }

main()

{   int p;

        while((p=fork())==-1);

        if(p==0) //子进程

        {   k=1;

           signal(10,func);

           while(k!=0);

           printf("Child process is killed by parent!\n");

        }

        else //父进程

        {   sleep(1);

           kill(p,10);

           wait(0);

           printf("Parent process has killed!\n");

        }  

}

编译及执行过程和结果截屏:

程序实现功能(父进程和子进程分别做了什么?):

父进程先执行,创建子进程后休眠 1 秒,然后向子进程发送信号,并等待子进程退出。在这种情况下,子进程接收到信号后,执行 func() 函数,将 k 置为 0,然后打印 "Child process is killed by parent!"。随后父进程继续执行,打印 "Parent process has killed!"。

子进程先执行,在接收到信号后执行 func() 函数,将 k 置为 0,然后退出。父进程接着执行,休眠 1 秒,然后尝试向已经退出的子进程发送信号,但是由于子进程已经退出,所以 kill() 函数失败。父进程继续执行,打印 "Parent process has killed!"。

父子进程竞争情况下,可能会出现不确定的结果。例如,父进程发送信号前子进程已经退出,这种情况下父进程会等待一个不存在的进程退出,可能会产生错误。

(2)

#include<unistd.h>

#include<signal.h>

#include<stdio.h>

int k=1;

void func()

{   k=0; }

main()

{

        signal(SIGINT,func);

        while(k!=0);

        printf("\n main process is killed by keybreak!\n");

}

编译及执行过程和运行结果截屏:

解释程序实现的功能:

1. 在程序运行期间,通过 `signal(SIGINT,func)` 函数调用注册了一个信号处理函数 `func()`。这意味着当程序接收到 `SIGINT` 信号时(通常由键盘输入 Ctrl+C 产生),将执行 `func()` 函数。

2. `func()` 函数被定义为将全局变量 `k` 的值设为 0。这表明当程序接收到 `SIGINT` 信号时,会将 `k` 的值修改为 0。

3. 主函数中的 `while(k!=0)` 循环会不断检查 `k` 的值是否为 0。如果 `k` 的值变为 0(即接收到了 `SIGINT` 信号),则循环结束。

4. 当循环结束时,程序会打印一条消息:"main process is killed by keybreak!"。这条消息表明主进程由于键盘输入而被终止。

因此,该程序的功能是当用户在程序运行过程中按下 Ctrl+C 时,主进程会接收到 `SIGINT` 信号,执行 `func()` 函数将全局变量 `k` 的值设为 0,然后退出循环并打印提示消息,程序结束运行。

2、编写一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止: 

                       Child process 1 is killed by parent!

                       Child process 2 is killed by parent!

父进程等待两个子进程终止后,输出以下信息后终止:

                       Parent process is killed!

要求给出编译及执行过程和运行结果截屏。(2分)

#include<unistd.h>

#include<signal.h>

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<sys/wait.h>



int k=1;



void func()

{

    k=0;

}



int main()

{

    signal(SIGINT, func);

    while (k != 0);

    int p1, p2;

    while ((p1=fork()) == -1);

    if (p1 == 0) // 第一个子进程

    {

        k=1;

        signal(10, func);

        while (k != 0);

        printf("Child process 1 is killed by parent!\n");

        exit(0);

    }

    else // 父进程

    {

        sleep(1);

        while ((p2=fork()) == -1);

        if (p2 == 0) // 第二个子进程

        {

            k=1;

            signal(10, func);

            while (k != 0);

            printf("Child process 2 is killed by parent!\n");

            exit(0);

        }

        else // 父进程

        {

            sleep(1);

            kill(p1, 10);

            kill(p2, 10);

            printf("Parent process is killed!\n");

        }  

    }



    return 0;

}

在父进程中,使用 signal(SIGINT, func) 注册了 SIGINT 信号的处理函数 func,这表示当父进程收到 SIGINT 信号(通常是通过键盘输入 Ctrl+C 产生)时,会将全局变量 k 设为 0。

父进程进入了一个无限循环,等待 k 的值变为 0。这意味着父进程会一直等待直到收到 SIGINT 信号,或者其他方式修改了 k 的值。

父进程创建了两个子进程 p1 和 p2。每个子进程执行类似的操作:在无限循环中等待 k 的值变为 0,然后输出相应的消息并终止。

在父进程中,先创建并杀死了第一个子进程 p1,然后创建并杀死了第二个子进程 p2。之后输出了 "Parent process is killed!" 消息。

为了演示父子进程之间的信号通信。父进程通过键盘输入 Ctrl+C 触发 SIGINT 信号,子进程通过 SIGUSR1 信号接收到父进程的通知,然后输出相应的消息。这种方式可以通过信号来实现进程之间的通信和协作。

3、编写程序,利用信号实现司机售票员同步操作问题。要求给出编译及运行过程和结果截图。(2分)

参考程序框架:

#include<unistd.h>

#include<signal.h>

#include<stdio.h>

#include<stdlib.h>

#include<sys/types.h>

#include<sys/wait.h>

int k;

void func()

{   k=0; }

main()

{   int p;

    int count=3;

    signal(12,func);      

    while((p=fork())==-1);

    if(p>0) //司机进程

    {   while(count)

        {   k=1;

           sleep(1);

           printf("driver:drive\n");

           printf("driver:stop\n");

               kill(p,10);         //发送信号给售票员

           while(k);

           printf("driver:start\n");

           count--;

        }

    }else //售票员进程

    {   signal(10,func);

        while(count)

        {   k=1;

           printf("conductor:sell ticket.\n");

           while(k);

           printf("conductor:open door.\n");

           printf("conductor:close door.\n");

  int ppid = getppid();     //取得司机进程的识别码

               kill(ppid,12); //发送信号给司机

           count--;

        }

    }

}

编译及执行过程和结果截屏:

1. 首先,在主函数中定义了两个变量 `p` 和 `count`。`p` 用于保存 `fork()` 函数的返回值,`count` 用于表示循环执行的次数。

2. 使用 `signal(12, func)` 注册了信号处理函数 `func()`,该函数在接收到编号为 12 的信号时会将全局变量 `k` 设为 0。编号为 12 的信号在程序中用于司机和售票员之间的通信。

3. 在一个循环中,通过 `fork()` 创建了子进程。父进程中 `p` 的值大于 0,而子进程中 `p` 的值等于 0。

4. 如果是父进程(司机进程),则执行如下操作:

   - 将 `k` 设为 1,表示司机正在驾驶。

   - 打印 "driver:drive",表示司机正在驾驶。

   - 打印 "driver:stop",表示司机停车。

   - 通过 `kill(p, 10)` 向售票员进程发送信号 10(`SIGUSR1`),告知售票员停车。

   - 进入循环,等待售票员处理完毕(`k` 变为 0),然后再次开始驾驶。

5. 如果是子进程(售票员进程),则执行如下操作:

   - 使用 `signal(10, func)` 注册了信号处理函数,该函数在接收到编号为 10 的信号时将 `k` 设为 0。

   - 进入循环,等待司机停车信号。

   - 收到司机停车信号后,将 `k` 设为 1,表示售票员正在处理。

   - 打印 "conductor:sell ticket.",表示售票员正在售票。

   - 发送信号 12(`SIGUSR2`)给司机进程,告知司机售票员已经完成任务。

   - 等待司机开始行驶的信号。

6. 程序最终会按照循环的次数执行上述操作,直到循环结束。

4、编制一段程序,实现进程的管道通信。使用pipe()建立一条管道线。两个子进程p1和p2分别向管道各写一句话:

            Child 1 is sending message!

            Child 2 is sending message!

而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。(1分)

<参考程序>

#include<unistd.h>

#include<signal.h>

#include<stdio.h>

#include<stdlib.h>

int pid1,pid2;

main()

{   int fd[2];

    char OutPipe[100],InPipe[100];

    pipe(fd);

    while((pid1=fork())== -1);

    if(pid1==0)

    {   sprintf(OutPipe,"child 1 process is sending message!");

        write(fd[1],OutPipe,50);

        sleep(5);

        exit(0);

    }

    else

    {   while((pid2=fork())==-1);

        if(pid2==0)

        {   sprintf(OutPipe,"child 2 process is sending message!");

            write(fd[1],OutPipe,50);

            sleep(5);

            exit(0);

        }

        else

        {   wait(0);

            read(fd[0],InPipe,50);

            printf("%s\n",InPipe);

            wait(0);

            read(fd[0],InPipe,50);

            printf("%s\n",InPipe);

            exit(0);

        }

    }

}

编译及执行过程和运行结果截屏。

这段代码实现了一个父进程创建两个子进程的过程,其中每个子进程都向父进程通过管道发送一条消息,然后父进程接收这两条消息并输出

1. 父进程创建了一个管道 `fd`,用于父子进程之间的通信。

2. 父进程通过 `fork()` 创建了第一个子进程 `pid1`。如果创建失败,则继续尝试创建,直到成功为止。

3. 如果当前进程是第一个子进程,则向管道中写入一条消息 "child 1 process is sending message!",然后睡眠 5 秒后退出。

4. 如果当前进程是父进程,则继续创建第二个子进程 `pid2`,并进行类似的操作。

5. 如果当前进程是第二个子进程,则向管道中写入一条消息 "child 2 process is sending message!",然后睡眠 5 秒后退出。

6. 父进程在两个子进程都退出后,使用 `wait()` 函数等待子进程退出,并通过管道读取两个子进程发送的消息。

7. 父进程读取管道中的消息,并打印输出。

总之该程序通过管道实现了父进程与两个子进程之间的通信,子进程向父进程发送了各自的消息,而父进程则接收并打印输出这些消息。

5、在父进程中用pipe()建立一条管道线,往管道里写信息,两个子进程接收父进程发送的信息。(2分)

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

#include <sys/wait.h>

#include <string.h>



int main() {

    int fd[2];

    pid_t pid1, pid2;

    char message[] = "父进程发送给子进程的消息";



    char buffer[100];



    if (pipe(fd) < 0) {

        perror("管道创建失败");

        exit(EXIT_FAILURE);

    }



    if ((pid1 = fork()) < 0) {

        perror("子进程1创建失败");

        exit(EXIT_FAILURE);

    }



    if (pid1 == 0) {

        // 子进程1

        close(fd[1]); // 关闭管道写端

        read(fd[0], buffer, sizeof(buffer));

        printf("子进程1接收到: %s\n", buffer);

        close(fd[0]); // 关闭管道读端

        exit(EXIT_SUCCESS);

    }



    if ((pid2 = fork()) < 0) {

        perror("子进程2创建失败");

        exit(EXIT_FAILURE);

    }



    if (pid2 == 0) {

        // 子进程2

        close(fd[1]); // 关闭管道写端

        read(fd[0], buffer, sizeof(buffer));

        printf("子进程2接收到: %s\n", buffer);

        close(fd[0]); // 关闭管道读端

        exit(EXIT_SUCCESS);

    }



    // 父进程

    close(fd[0]); // 关闭管道读端

    write(fd[1], message, strlen(message) + 1);

    write(fd[1], message, strlen(message) + 1);

    close(fd[1]); // 关闭管道写端



    wait(NULL);

    wait(NULL);



    return 0;

}

父进程通过管道向两个子进程发送消息,并且两个子进程分别接收并输出这些消息。

1. 创建了一个管道 `fd`,用于父子进程之间的通信。

2. 父进程通过 `fork()` 创建了两个子进程 `pid1` 和 `pid2`。

3. 子进程1中,关闭了管道的写端,然后通过管道的读端接收父进程发送的消息,并打印输出。

4. 子进程2中,同样关闭了管道的写端,然后通过管道的读端接收父进程发送的消息,并打印输出。

5. 父进程中,关闭了管道的读端,然后通过管道的写端向管道中写入两条消息,然后关闭了写端。

6. 父进程使用 `wait()` 函数等待两个子进程退出。

总之该程序通过管道实现了父进程向两个子进程发送消息的功能,而两个子进程分别接收并输出了父进程发送的消息。

6、编程用管道实现父子进程间的双向通信。要求给出设计思路,调试通过的程序和编译执行过程以及结果截屏。(附加题)

设计思路:

父进程创建两个管道,一个用于父进程向子进程发送消息,另一个用于接收子进程发送的消息。父进程创建子进程。子进程同样创建两个管道,一个用于子进程向父进程发送消息,另一个用于接收父进程发送的消息。父进程和子进程可以根据需要进行读取和写入管道。当父进程需要向子进程发送消息时,它将消息写入第一个管道,子进程从该管道读取消息。当子进程需要向父进程发送消息时,它将消息写入第二个管道,父进程从该管道读取消息。父子进程之间需要遵循一定的通信协议,以确保消息的正确传递和处理。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <string.h>



#define BUFFER_SIZE 100



int main() {

    int parent_to_child[2]; // 父进程向子进程发送消息的管道

    int child_to_parent[2]; // 子进程向父进程发送消息的管道

    pid_t pid;



    // 创建父进程向子进程发送消息的管道

    if (pipe(parent_to_child) == -1) {

        perror("pipe");

        exit(EXIT_FAILURE);

    }



    // 创建子进程向父进程发送消息的管道

    if (pipe(child_to_parent) == -1) {

        perror("pipe");

        exit(EXIT_FAILURE);

    }



    // 创建子进程

    pid = fork();

    if (pid == -1) {

        perror("fork");

        exit(EXIT_FAILURE);

    }



    if (pid == 0) { // 子进程

        close(parent_to_child[1]); // 子进程关闭向子进程发送消息的写端

        close(child_to_parent[0]); // 子进程关闭向父进程发送消息的读端



        // 子进程从父进程发送消息的管道读取消息并输出

        char buffer[BUFFER_SIZE];

        read(parent_to_child[0], buffer, BUFFER_SIZE);

        printf("子进程接收到父进程的消息:%s\n", buffer);



        // 子进程向父进程发送消息

        const char *msg_to_parent = "Hello, parent!";

        write(child_to_parent[1], msg_to_parent, strlen(msg_to_parent) + 1);



        exit(EXIT_SUCCESS);

    } else { // 父进程

        close(parent_to_child[0]); // 父进程关闭向子进程发送消息的读端

        close(child_to_parent[1]); // 父进程关闭向父进程发送消息的写端



        // 父进程向子进程发送消息

        const char *msg_to_child = "Hello, child!";

        write(parent_to_child[1], msg_to_child, strlen(msg_to_child) + 1);



        // 父进程从子进程发送消息的管道读取消息并输出

        char buffer[BUFFER_SIZE];

        read(child_to_parent[0], buffer, BUFFER_SIZE);

        printf("父进程接收到子进程的消息:%s\n", buffer);



        // 等待子进程退出

        wait(NULL);

    }



    return 0;

}

三、实验总结和体会(1分)

实验涉及了进程间通信的不同机制,分别是信号处理和管道通信。通过这些实验,你学习了如何在进程之间传递信息,以及如何利用不同的通信方式实现进程之间的协作和交互

进程间通信: 通过管道、信号等机制,你了解了不同进程间通信的方式和原理。通过这些实验,你掌握了进程间通信的基本概念,并且能够使用这些通信机制在多个进程之间进行数据交换和同步。

信号处理: 你研究了信号的基本概念和处理机制,包括注册信号处理函数、发送信号、处理信号等。通过信号处理,你可以实现进程间的异步通信和事件处理,对于编写并发和异步程序非常重要。

创建管道:使用 pipe() 系统调用创建管道,获取用于通信的文件描述符。

创建子进程:使用 fork() 系统调用创建子进程,使得父子进程共享同一份代码和数据,但各自拥有独立的地址空间。

父子进程间通信:父子进程通过管道进行通信。父进程向管道写入数据,子进程从管道读取数据;子进程向管道写入数据,父进程从管道读取数据。

关闭文件描述符:在通信完成后,需要关闭未使用的文件描述符,以释放资源。

子进程退出:子进程在完成任务后通过 exit() 函数退出,避免成为僵尸进程。

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

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

相关文章

【js逆向专题】1.js语法基础

小节目标: 逆向工具准备熟悉 逆向的基本过程熟悉 JavaScript语法 一.前期准备 1. 技术准备 python基础语法爬虫基础功底JavaScript基础语法知识(可以自己偷偷的学习一些) 2. 工具准备 node解释器 官网地址:https://nodejs.org/zh-cn (推荐安装版本16版本) 把提供的软件…

网络层 IV(ARP、DHCP、ICMP)【★★★★★★】

&#xff08;★★&#xff09;代表非常重要的知识点&#xff0c;&#xff08;★&#xff09;代表重要的知识点。 一、地址解析协议&#xff08;ARP&#xff09;&#xff08;★★&#xff09; 在局域网中&#xff0c;由于硬件地址已固化在网卡上的 ROM 中&#xff0c;因此常常将…

Gartner报告解读:如何帮助企业完善数据分析与治理路线图

Gartner服务于全球100多个国家和地区的14,000余家机构&#xff0c;是一家深受客户信赖、观点客观的研究顾问公司。Garnter洞察、建议和工具可帮助您发现创新机遇&#xff0c;完成关键优先任务&#xff0c;助您成为企业不可或缺的战略专家和价值创造者。该公司是标普 500 指数成…

ET6框架(八)事件系统

文章目录 一、事件的定义二、定义异步事件 一、事件的定义 我们打开Client > Unity.Model > Codes > Model > Demo > EventType.cs 即可以查看目前工程中的事件 我们可以此添加事件结构体 我们还需要定义一个事件接收方法&#xff0c;创建路径文件夹及脚本 …

84、 k8s的pod基础+https-harbor

一、pod基础&#xff1a; pod进阶&#xff1a;探针&#xff08;面试必问—扩缩容&#xff0c;挂载&#xff09; 1.1、pod的定义 pod是k8s里面的最小单位&#xff0c;pod也是最小运行容器的资源对象。 容器时基于pod在k8s集群当中工作。 在k8s集群当中&#xff0c;一个pod就…

基于Android+SQLite数据库开发Java考试App

项目简介 Java课程考试App是基于AndroidStudio和SQLite数据库开发的一款App可以实现教师考生双端登录并使用相应功能。以Java课程作为设计主题&#xff0c;针对它们设计、实现一个考试APP。满足教师用户通过APP进行考生管理&#xff08;考生信息的增删改查&#xff09;、试题管…

Python 项目及依赖管理工具技术选型

Python 项目及依赖管理工具&#xff0c;类似于 Java 中的 Maven 与 Node 中的 npm webpack&#xff0c;在开发和维护项目时起着重要的作用。使用适当的依赖管理工具可以显著提高开发效率&#xff0c;减少依赖冲突&#xff0c;确保项目的稳定性、可靠性和安全性。 一、常见项目…

怎样把图片转换成pdf文件?分享图片转PDF的九个转换方法(新)

图片转为pdf怎么弄&#xff1f;图片和pdf是两种完全不同的文件类型&#xff0c;图片转pdf的是一个比较常见的格式转换需求&#xff0c;尤其是需要分享图片合集时。 图片转换成pdf文件可以借助专业的pdf转换器实现&#xff0c;只需要简单几个步骤就能轻松搞定。无论是图片转pdf&…

北斗系统助力低空经济腾飞:未来发展无限可能

近年来&#xff0c;随着科技的飞速发展&#xff0c;北斗卫星导航系统&#xff08;Beidou Satellite Navigation System, BDS&#xff09;在我国乃至全球范围内的应用日益广泛。尤其在低空经济领域&#xff0c;北斗系统作为新基建的重要组成部分&#xff0c;正在发挥着不可替代的…

JMeter之上传文件同时带有参数

文章目录 业务场景使用坑 业务场景 针对下述接口构建jmeter测试&#xff0c;这是个post接口&#xff0c;在上传文件file的同时指定变量groupId的值 PostMapping("/importExcel")public ApiResultDto<String> importExcel(TagChildrenImportDto importDto) {Sec…

Python中对象操作函数

Python中的对象操作函数包括help()、dir()、type()、ascii()等。 1 help()函数 help()函数可以查看指定函数的帮助信息&#xff0c;使用方法如图1所示。 图1 help()函数的使用方法 图1中所示的代码查看了“sorted”函数的帮助信息&#xff0c;包括该函数的作用、参数以及返回…

x264 编码器 AArch64汇编系列:DCT 变换相关汇编函数

DCT变换 在x264_dct_init函数中初始化具体的 dct 实现函数。 4x4 块DCT 变换 c 语言版本实现 4x4DCT 变换函数:sub4x4_dct。pixel_sub_wxh 函数: 这个函数的作用是从两个像素块中减去一个像素块,得到差分值,这些差分值将用于DCT变换。参数: diff:指向存储结果差分值的数组…

高标准城市照明智能化应用,创新城市节能之光

项目背景 在国家推动节约型、智慧化发展的背景下&#xff0c;该城市照明系统亟需智能化升级&#xff0c;以解决现有依赖传统时控器的局限性、能源浪费与照明不足的矛盾&#xff0c;以及依赖人工巡查和市民反馈的低效率、高成本维护等问题。通过引入智能控制系统&#xff0c;实现…

RKNPU2从入门到实践 --- 【10】RKNPU2零拷贝API实现RKNN模型在RK3588开发板上的部署

目录 一、为什么叫零拷贝API&#xff1f; 二、零拷贝API执行流程&#xff08;代码解读&#xff09; 2.1 前奏工作 2.2 main.cc文件的编写&#xff08;代码的编写&#xff09; 2.2.1 第一步&#xff1a;rknn_init接口创建rknn_context对象、加载RKNN模型 2.2.2 第二步…

产品概述Tektronix泰克TCP0030A电流探头TCP0030原装二手

产品概述 Tekronix TCP0030 AC/DC 电流探头是一款高性能且易于使用的探头&#xff0c;它通过可选测量范围增强了带宽&#xff0c;同时还提供了低电流测量能力和精度。Tektronix TCP0030 探头专为具有 TekVPI 探头接口的示波器而设计。 Tektronix TCP0030 AC/DC 电流探头的功能…

浏览器播放RTSP流,支持H264、H265等格式,支持IE、Chrome等浏览器

目录 背景 解决方案 效果 代码 前端代码 后端代码 下载 背景 项目中需要在浏览器中播放RTSP流&#xff0c;实在是不想折腾ActiveX控件 1、麻烦&#xff08;开发麻烦、使用时设置也麻烦&#xff09; 2、非IE浏览器不兼容 解决方案 使用OpenCvSharpNancy写一个解码服…

uniapp秋云图表报错json underfind的原因

如果在使用秋云图表 出现报错 以及只有第一次能够渲染正确的图表 后续刷新都不显示 那么大概率都是因为在刷新页面数据的时候 图标组件自己先执行了一遍&#xff0c;导致在第一遍的时候找不到值而报错 如图所示 只需要在加载数据的时候 加个延时 就可以很好的解决这个问题

记录一下腾讯云即时通信IM(无UI集成)、TRTC做文字、语音、图片、实时音视频聊天遇到的问题

文章目录 简单记录一下通讯IM和TRTC的一些坑&#xff1a;&#xff08;有其他坑再补充......&#xff09;isReady() 一直返回falseSDK_READY监听有时候会不触发getConversationList拉取会话&#xff0c;消息数据里的cloudCustomData经常会丢移动端发图片消息总是卡顿im里的信令消…

SpringBoot+redis+aop处理黑白名单

提示&#xff1a;SpringBootredisaop处理黑白名单 文章目录 目录 文章目录 1.导包 2.配置文件 3.代码 1.返回类型 2.redis 3.redisUtils 4.controller 5.AOP 6.具体实现 4.APIFox压力测试 1.导包 <dependencies><dependency><groupId>org.springf…

Mybatis基础操作学习

文章目录 实施前的准备工作&#xff1a;基础操作演示删除新增修改&#xff08;更新&#xff09;查询条件查询 实施前的准备工作&#xff1a; 准备数据库表创建一个新的springboot工程&#xff0c;选择引入对应的起步依赖&#xff08;mybatis、mysql驱动、lombok&#xff09;ap…