【进程与线程】进程之间的通信

这篇文章详细解释进程间通信(IPC)的各种方式,包括早期的方法、System V的机制以及现代的套接字。早期的是无名管道、有名管道和信号。System V的包括消息队列、共享内存和信号量。现在主要使用套接字,特别是网络编程中的应用,套接字实现了不同主机之间的通信,是现在最常用的主流通信方式。

大纲:

  1. 无名管道(匿名管道)
  • 用于有亲缘关系的进程间通信,比如父子进程。

  • 半双工,单向通信。

  • 使用pipe()系统调用创建。

  • 需要记得关闭不需要的文件描述符。

  • 示例代码可能包括创建管道,fork进程,然后父子进程分别读写。

  1. 有名管道(FIFO)
  • 可以在无关进程之间使用,因为通过文件系统中的命名管道文件进行通信。

  • 使用mkfifo()创建,然后像普通文件一样打开、读写。

  • 需要处理阻塞问题,比如同时打开读写端。

  1. 信号(Signal)
  • 用于通知进程发生了某个事件,比如中断或子进程终止。

  • 使用kill()发送信号,signal()或sigaction()注册处理函数。

  • 需要注意信号处理函数的可重入性和异步安全。

  1. System V IPC
  • 消息队列:允许进程发送格式化的数据块,每个消息有类型,可以非先进先出顺序读取。

  • 共享内存:多个进程可以访问同一块内存区域,需要配合信号量进行同步。

  • 信号量:用于进程间同步,控制对共享资源的访问。

  1. 套接字(Socket)
  • 支持不同主机间的通信,可以是TCP或UDP。

  • 本地套接字也可以用于同一台机器上的进程通信。

  • 涉及bind(), listen(), accept(), connect(), send(), recv()等函数。

接下来,对于每个部分的细节进行详细解析,比如API函数的参数、使用步骤,以及示例代码的正确性。同时,要注意对比不同IPC机制的特点,比如速度、复杂度、适用场景等。

我提供的代码在我的Ubuntu上运行是可行的,您可以直接复制粘贴使用即可。为了确保示例代码的正确性和简洁性,特别是信号处理和共享内存同步部分,这些地方容易出错。你在使用我的代码的时候,还是需要检查每个系统调用的返回值,处理错误情况,比如管道或FIFO创建失败时的处理。在基于对编程流程的理解之上,进行代码复用(不要无脑抄,谢谢)。

我会确保文章的结构清晰,每个IPC方法分点说明,特点、API、示例分开展示,便于读者理解。

进程间通信(IPC)的详细分类和说明,涵盖早期、System V 和现代方法:

早期:无名管道有名管道信号通信System V:消息队列共享内存信号量现在:套接字  --- 网络编程 -- 实现了不同主机之间的通信无名管道: --  管道在内核空间注意事项:1 - 无名管道只能作用域亲缘关系之间的进程通信2 - 无名管道有固定的读端以及写端3 - 如果管道中无数据,则读操作会阻塞4 - 无名管道不能用于存储数据5 - 如果没有读操作则写操作没有意义6 - 如果管道满了则写操作会阻塞 7 - 是一个半双工通信单工:数据只能单向传递  A ---> B双工:数据可以双向发送  A <---> B半双工通信:数据在同一时刻只能单向发送全双工通信:数据可以在任意时刻双向发送有名管道:特点:1- 有名字 -- 由文件的实体2- 有名管道可以作用于非亲缘进程间的通信3- 可以使用文件IO的相关函数进行操作4- 管道只是数据的传递,本身不存储任何数据,管道文件大小恒定为05- 管道文件不能光标的偏移和定位(fseek/ftell禁用)6- 如果管道中没有数据则读操作会阻塞7- 每次读数据能够读取到 size个大小8- 全双工通信信号通信 特点:1- 唯一的异步通信2- 信号属于内核的内容3- 信号不直接传输数据,只是给一个提醒4- 不能自定义信号5- 进程对信号的响应方式5.1> 默认处理(缺省操作) 9) SIGKILL  19) SIGSTOP  只能默认处理 ***5.2> 自定义处理(信号捕捉) 10) SIGUSR1 12) SIGUSR2 只能被捕捉 *****5.3> 忽略处理 SIGKILL及SIGSTOP 不能被忽略 ****6- 软件层次上对中断机制的模拟------------------------------------------------------------------------------------         IPC通信对象:  Inter  Process CommunicationSystem V:共享内存信号量消息队列1-共享内存1> 共享内存是内核实际存在的一块物理内存 2> 共享内存是通信效率最高的通信方式3> 共享内存的读操作主动不会阻塞(共享内存的数据不会主动消失,bzero清空后,读操作也会阻塞); -------------------------------------key        shmid      owner      perms      bytes      nattch          status 键值        id号       拥有者    权限       大小       当前使用的进程数       状态操作:1> 获得键值- 直接指定 -- 容易重复- 系统自带的宏 - IPC_PRIVAT - 只会创建不会打开- ftok() 自动获取 - 推荐2> 打开/创建 共享内存 共享内存的ID号 =  shmget(key,大小,权限);3> 映射共享内存映射后的地址 =  shmat(ID号,NULL,权限);0 : 可读可写SHM_RDONLY:只读映射成功后就可以进行读写操作了4> 取消映射shmdt(映射后的地址);5> 删除共享内存 -- 可选shmctl() -- 操作共享内存shmctl(ID号,指令选择,存放信息的结构体)cmd:IPC_STAT : 查看属性IPC_SET  : 设置属性IPC_RMID : 删除共享内存------------------------------------------------------------------------------------        	   2-信号量 - 信号灯注意: 和信号没有任何关系1> 信号灯是内核VAL资源2> PV操作 P操作:申请资源 V:释放资源3> IPC创建的是信号灯集4> 信号灯不进行任何数据的传输,作为实现进程同步的工具5> 信号灯的值不会主动归0key        semid      owner      perms      nsems 信号灯集中信号灯的个数操作:1-获得键值 - 同共享内存2-打开/创建 信号灯集信号灯集ID =  semget(key,信号灯的个数,权限 -shmget一样)3- 执行PV操作semop(ID号, 指令选择,要操作信号灯的个数)指令选择:struct sembuf{unsigned short sem_num;  /* semaphore number 信号灯的编号*/short          sem_op;   /* semaphore operation PV操作的选择  */// P: <0   V: >0short          sem_flg;  /* operation flags 权限选择 */0, 会阻塞进程 IPC_NOWAIT, 不会阻塞进程 } 4- 操作信号灯集semctl(ID号,信号灯的编号,指令选择,/* 相关信息的联合体 */)指令选择:SETVAL:设置信号灯的值  -- 此时需要第四个参数GETVAL:用于查看信号灯的值IPC_RMID:删除信号灯union semun {int              val;    /* Value for SETVAL 信号灯更改值 */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO(Linux-specific) */};  1-消息队列 1> 先进先出的队列2> 消息队列的格式:  消息类型 + 消息正文key        msqid      owner      perms      used-bytes              messages  已经使用的字节数        当前消息队列中未读的消息数------------------------------------------------------------------------------------   Uinx 套接字. Unix 套接字可用于本地进程间通信。. 创建套接字时使用本地协议 PF_LOCAL / PF_UNIX / AF_LOCAL / AF_UINX。. 可以创建流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),面向连接的套接字(SOCK_SEQPACKET)。数据报套接字是可靠的,既不会丢失消息,也不会传递出错。. Unix 套接字是套接字和管道之间的混合物。. 和其他进程间通信方式比,Unix 本地套接字使用方便,效率也高。因为它不需要经过网络协议栈、不需要打包拆包、不需要计算校验和、不需要维护序号和应答等,只是将应用层数据从一个进程复制到另一个进程。. 常用于前后台进程通信,比如 X Window。. 另外,Unix 本地套接字可用于传递文件描述符、传递用户凭证等场景。Unix 套接字地址类型:struct sockaddr_un {sa_family_t sun_family;               /* AF_UNIX */char        sun_path[108];            /* pathname */};Unix 套接字在 struct sockaddr_un 结构体的 sun_path 数组中有三种不同的地址类型:. pathname 文件系统文件名。服务器和客户端可各自指定文件系统中的文件名,这个文件名的类型是套接字类型(在 ls -l 的模式中含 s,如 srw-rw-r--),文件名必须是以空字符结束的字符串。文件名保存在 sun_path 数组中,因此长度不能超 107。此地址必须调用 bind() 进行绑定。该文件用仅于向客户进程告知套接字名称,既不能打开,也不能由应用程序用于通信。如果在 bind() 时该文件已存在则 bind() 失败,关闭套接字时它也不会自动删除。因此一般在应用程序结束前删除它。为可移植性考虑,绑定时的地址长度可以使用以下方法计算:offsetof(struct sockaddr_un, sun_path) + strlen(sun_path)offsetof() 是在 <stddef.h> 中定义的宏,它计算 sun_path 成员从结构开始处的偏移量。. 无名。未用 bind() 绑定的流套接字是无名的,同样地用 socketpair() 创建的两个套接字也是无名的。显然如果使用 bind() 的话则只有客户端可以使用无名套接字,而服务器不能使用无名套接字,因为那样客户端发送给谁?用 socketpair() 创建的两个套接字因为是无名的,因此只能用于有亲缘关系的进程。. 抽象文件名。使用抽象文件名的好处是不用在文件系统中创建文件,也不删除文件。在 sun_path[0] 中指定空字符 '\0',即可使用抽象文件名的套接字。又分两种情况,一是将抽象文件名保存在sun_path[1] 开始处,注意名称长度不能超过 106。绑定时地址长度可按以下计算:offsetof(struct sockaddr_un, sun_path) + strlen(sun_path + 1) + 1这种情况服务器和客户端都可以使用抽象文件名。二是自动生成抽象文件名。即清空 sun_path 数组,而绑定的地址长度为:offsetof(struct sockaddr_un, sun_path)自动生成的抽象文件名长度为 5 字节,字符范围是 [0-9a-f]。显然自动生成抽象文件名,也只能用于客户端。

一、早期 IPC 方法

1. 无名管道(匿名管道,Pipe)

详情请参见文章:【进程与线程】无名管道(匿名管道,Pipe)

  • 特点:
    • 仅适用于 父子进程或有亲缘关系的进程。
    • 半双工(单向通信),数据只能单向流动。
    • 基于文件描述符,通过内存缓冲区传输数据。
  • API
    • int pipe(int fd[2]):创建管道,fd[0] 为读端,fd[1] 为写端。
  • 示例:
#include <stdio.h>
#include <unistd.h>int main() {int fd[2];char buf[20];pipe(fd);  // 创建管道if (fork() == 0) {  // 子进程close(fd[0]);   // 关闭读端write(fd[1], "Hello", 6);close(fd[1]);} else {            // 父进程close(fd[1]);   // 关闭写端read(fd[0], buf, sizeof(buf));printf("Received: %s\n", buf);close(fd[0]);}return 0;
}
2. 有名管道(FIFO)

详情请参见文章:【进程与线程】有名管道(FIFO)

  • 特点:
    • 通过 文件系统中的命名管道文件 实现,无关进程可通信。
    • 支持 阻塞和非阻塞模式
  • API
    • int mkfifo(const char *path, mode_t mode):创建命名管道文件。

示例

// 进程 A(写端)
#include <stdio.h>
#include <fcntl.h>int main() {mkfifo("/tmp/myfifo", 0666);int fd = open("/tmp/myfifo", O_WRONLY);write(fd, "Hello FIFO", 11);close(fd);return 0;
}// 进程 B(读端)
#include <stdio.h>
#include <fcntl.h>int main() {int fd = open("/tmp/myfifo", O_RDONLY);char buf[20];read(fd, buf, sizeof(buf));printf("Received: %s\n", buf);close(fd);return 0;
}
3. 信号(Signal)

详情请参见文章:【进程与线程】信号(Signal)

  • 特点
    • 用于 异步通知进程 某个事件的发生(如 SIGINTSIGTERM)。
    • 信号处理函数需简短且可重入。
  • API
    • void (*signal(int sig, void (*handler)(int)))(int):注册信号处理函数。
    • int kill(pid_t pid, int sig):向指定进程发送信号。

示例

#include <stdio.h>
#include <signal.h>
#include <unistd.h>void handler(int sig) {printf("Received signal: %d\n", sig);
}int main() {signal(SIGINT, handler);  // 捕获 Ctrl+Cwhile (1) {sleep(1);}return 0;
}

二、System V IPC

1. 消息队列(Message Queue)
  • 特点
    • 消息按类型存储,支持 优先级读取
    • 独立于进程存在(需显式删除)。
  • API
    • int msgget(key_t key, int msgflg):创建或获取消息队列。
    • int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg):发送消息。
    • ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg):接收消息。

示例

// 发送端
#include <sys/msg.h>
struct msgbuf {long mtype;char mtext[100];
};int main() {int msqid = msgget(1234, IPC_CREAT | 0666);struct msgbuf msg = {1, "Hello Message Queue"};msgsnd(msqid, &msg, sizeof(msg.mtext), 0);return 0;
}// 接收端
int main() {int msqid = msgget(1234, 0666);struct msgbuf msg;msgrcv(msqid, &msg, sizeof(msg.mtext), 1, 0);printf("Received: %s\n", msg.mtext);msgctl(msqid, IPC_RMID, NULL);  // 删除队列return 0;
}
2. 共享内存(Shared Memory)
  • 特点
    • 速度最快 的 IPC 方式,进程直接读写同一内存区域。
    • 需配合信号量同步。
  • API
    • int shmget(key_t key, size_t size, int shmflg):创建或获取共享内存。
    • void *shmat(int shmid, const void *shmaddr, int shmflg):附加共享内存。
    • int shmdt(const void *shmaddr):分离共享内存。

示例

// 写入端
#include <sys/shm.h>
int main() {int shmid = shmget(1234, 1024, IPC_CREAT | 0666);char *shm = shmat(shmid, NULL, 0);sprintf(shm, "Hello Shared Memory");shmdt(shm);return 0;
}// 读取端
int main() {int shmid = shmget(1234, 1024, 0666);char *shm = shmat(shmid, NULL, 0);printf("Received: %s\n", shm);shmdt(shm);shmctl(shmid, IPC_RMID, NULL);  // 删除共享内存return 0;
}
3. 信号量(Semaphore)
  • 特点
    • 用于 进程间同步,控制对共享资源的访问。
    • 支持原子操作(P/V 操作)。
  • API
    • int semget(key_t key, int nsems, int semflg):创建或获取信号量集。
    • int semop(int semid, struct sembuf *sops, size_t nsops):执行信号量操作。

示例

#include <sys/sem.h>int main() {int semid = semget(1234, 1, IPC_CREAT | 0666);semctl(semid, 0, SETVAL, 1);  // 初始化信号量为1struct sembuf op = {0, -1, 0};  // P操作(获取资源)semop(semid, &op, 1);printf("Critical section start\n");sleep(2);printf("Critical section end\n");op.sem_op = 1;  // V操作(释放资源)semop(semid, &op, 1);semctl(semid, 0, IPC_RMID);  // 删除信号量return 0;
}

三、现代 IPC:套接字(Socket)

  • 特点
    • 支持 跨网络通信(TCP/UDP)。
    • 本地套接字(Unix Domain Socket)也可用于同一主机的进程通信。
    • 全双工通信。
  • API
    • socket():创建套接字。
    • bind()listen()accept()(服务端)。
    • connect()send()recv()(客户端)。

示例(本地 TCP 通信):

// 服务端
#include <sys/socket.h>
#include <sys/un.h>int main() {int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);struct sockaddr_un addr = {AF_UNIX, "/tmp/mysocket"};bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));listen(sockfd, 5);int client = accept(sockfd, NULL, NULL);send(client, "Hello Socket", 12, 0);close(client);close(sockfd);unlink("/tmp/mysocket");return 0;
}// 客户端
int main() {int sockfd = socket(AF_UNIX, SOCK_STREAM, 0);struct sockaddr_un addr = {AF_UNIX, "/tmp/mysocket"};connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));char buf[20];recv(sockfd, buf, sizeof(buf), 0);printf("Received: %s\n", buf);close(sockfd);return 0;
}

对比与适用场景

根据适合场景的需求选择合适的 IPC 机制

  1. 简单通信:无名管道、信号。
  2. 高性能共享:共享内存 + 信号量。
  3. 跨网络通信:套接字。
IPC 方法速度复杂度适用范围同步需求
无名管道父子进程无需显式同步
有名管道(FIFO)任意进程无需显式同步
信号异步通知信号处理函数
消息队列任意进程内置消息类型管理
共享内存最快高性能数据共享需信号量同步
信号量进程同步原子操作
套接字跨网络或本地进程协议层控制

以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。

我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[AUTOSAR通信] - PDUR模块解读

点击订阅专栏不迷路 文章目录 一、 PDUR模块概述二、功能描述2.1 发送路由功能2.2 接收路由功能2.3 网关路由功能2.4 路由控制功能 三、配置項介紹3.1. PduRBswModules3.2. PduRGeneral3.3. PduRRoutingTables3.4. PduRRoutingPath3.5. PduRSrcPdu3.6. PduRDestPdu 四、总结 &g…

分治下的快速排序(典型算法思想)—— OJ例题算法解析思路

目录 一、75. 颜色分类 - 力扣(LeetCode) 运行代码: 一、算法核心思想 二、指针语义与分区逻辑 三、操作流程详解 四、数学正确性证明 五、实例推演(数组[2,0,2,1,1,0]) 六、工程实践优势 七、对比传统实现 八、潜在问题与解决方案 九、性能测试数据 十、扩展…

分层耦合 - IOC详解

推荐使用下面三种, 第一种多用于其他类 声明bean的时候&#xff0c;可以通过value属性指定bean的名字&#xff0c;如果没有指定&#xff0c;默认为类名首字母小写。 使用以上四个注解都可以声明bean&#xff0c;但是在springboot集成web开发中&#xff0c;声明控制器bean只能用…

PDF Shaper:免费多功能 PDF 工具箱,一站式满足您的 PDF 需求!

​PDF Shaper 是一款功能强大且完全免费的 PDF 工具箱&#xff0c;它几乎涵盖了日常 PDF 操作的方方面面&#xff0c;无论是转换、编辑还是处理&#xff0c;都能轻松搞定。以下是这款软件的详细介绍&#xff1a; 功能丰富&#xff0c;一应俱全 PDF 转换功能强大 PDF 转 Word&am…

未来替代手机的产品,而非手机的本身

替代手机的产品包括以下几种&#xff1a; 可穿戴设备&#xff1a;智能手表、智能眼镜等可穿戴设备可以提供类似手机的功能&#xff0c;如通话、信息推送、浏览网页等。 虚拟现实&#xff08;VR&#xff09;技术&#xff1a;通过佩戴VR头显&#xff0c;用户可以进行语音通话、发…

deepseek+“D-id”或“即梦AI”快速生成短视频

1、deepseek生成视频脚本 1.1、第一步&#xff1a;使用通用模板提出需求&#xff0c;生成视频脚本 对话输入示例脚本1&#xff1a; 大年初五是迎财神的日志&#xff0c;帮我生成10秒左右的短视频&#xff0c; 体现一家3口在院子里欢庆新年&#xff0c; 孩子在院子里放鞭炮烟…

在CT107D单片机综合训练平台上实现外部中断控制LED闪烁

引言 在单片机开发中&#xff0c;外部中断是一个非常重要的功能&#xff0c;它可以让单片机在检测到外部信号变化时立即做出响应。本文将详细介绍如何在CT107D单片机综合训练平台上使用外部中断来控制LED灯的闪烁。我们将使用两种不同的方式来实现这一功能&#xff1a;一种是在…

为什么推荐使用 LabVIEW 开发

在仪器行业的软件开发中&#xff0c;LabVIEW 以其图形化编程、快速原型开发、高效硬件集成的优势&#xff0c;成为自动化测试和控制系统的理想选择。尽管一些工程师仍然坚持使用 C 语言&#xff0c;但这更多是出于习惯&#xff0c;而非技术上的必然。LabVIEW 不仅支持 NI 硬件&…

力扣1448. 统计二叉树中好节点的数目

Problem: 1448. 统计二叉树中好节点的数目 文章目录 题目描述思路复杂度Code 题目描述 思路 对二叉树进行先序遍历&#xff0c;边遍历边对比并更新当前路径上的最大值pathMax&#xff0c;若当pathMax小于等于当前节点值&#xff0c;则好节点的数目加一 复杂度 时间复杂度: O (…

DeepSeek帮助做【真】软件需求-而不是批量刷废话

尝试给DeepSeek一份系统用例规约&#xff0c;让它帮判断哪些地方还没有覆盖涉众利益。结果见以下 需求工作的重点可以放在建模精细的真实现状流程和精细的真实涉众利益上&#xff0c;AI帮助推演系统需求。

【JVM详解五】JVM性能调优

示例&#xff1a; 配置JVM参数运行 #前台运行 java -XX:MetaspaceSize-128m -XX:MaxMetaspaceSize-128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio8 - XX:UseConcMarkSweepGC -jar /jar包路径 #后台运行 nohup java -XX:MetaspaceSize-128m -XX:MaxMetaspaceS…

Qt文本处理【正则表达式】示例详解:【QRegularExpression】

在 Qt 中&#xff0c;正则表达式是处理文本的强大工具&#xff0c;它能够帮助我们匹配、搜索和替换特定的字符串模式。自 Qt 5 起&#xff0c;QRegularExpression 类提供了对 ECMAScript 标准的正则表达式支持&#xff0c;这使得它在处理各种复杂的字符串任务时变得更加高效和灵…

【算法学习】拓扑排序(Topological Sorting)

目录 定义 例子 拓扑排序的实现 核心思想 实现方法 1&#xff0c;Kahn算法&#xff08;基于贪心策略&#xff09; 步骤&#xff1a; 用二维数组存储图的例子 用哈希表存储图的例子 2&#xff0c;基于DFS的后序遍历法 总结 拓扑排序的应用场景 1&#xff0c;任务调度 …

JavaEE-前端与后台的搭建

一.idea连接数据库 在使用 IntelliJ IDEA 连接数据库时&#xff0c;可以按照以下步骤操作&#xff1a; ### 1. 打开数据库工具窗口 - 在 IntelliJ IDEA 中&#xff0c;点击右侧的 Database 工具窗口&#xff0c;或通过 View -> Tool Windows -> Database 打开。 ### 2. 添…

华为Mate 70 Pro或推出全新版本

关于华为Mate 70 Pro或推出全新版本的相关内容&#xff1a;可能的版本及命名。 据数码博主“定焦数码”爆料&#xff0c;华为Mate 70 Pro将推出新版本&#xff0c;命名为“优享版”。这一命名方式与华为Mate 60系列中的Mate 60 Pro乐臻版类似&#xff0c;预计优享版也会是一个组…

Linux 实操篇 实用指令

一、远程登录到Linux服务器 &#xff08;1&#xff09;为什么需要远程登录Linux linux服务器是开发小组共享的正式上线的项目是运行在公网因此程序员需要远程登陆到Linux进行项目管理或者开发画出简单的网络拓扑示意图远程登陆客户端有Xshell6&#xff0c;Xftp6&#xff0c;我…

SpringBoot 统一功能处理之拦截器、数据返回格式、异常处理

目录 拦截器 一、什么是拦截器 二 拦截器的使用 三 拦截路径配置 四 拦截器的执行流程 统一数据返回格式 统一异常处理 拦截器 一、什么是拦截器 拦截器是Spring框架提供的核心功能之一&#xff0c;主要用来拦截用户的请求&#xff0c;在指定方法前后&#xff0c;根据业务…

Django学习笔记(第一天:Django基本知识简介与启动)

博主毕业已经工作一年多了&#xff0c;最基本的测试工作已经完全掌握。一方面为了解决当前公司没有自动化测试平台的痛点&#xff0c;另一方面为了向更高级的测试架构师转型&#xff0c;于是重温Django的知识&#xff0c;用于后期搭建测试自动化平台。 为什么不选择Java&#x…

Spring Cloud工程完善

目录 完善订单服务 启动类 配置文件 实体类 Controller Service Mapper 测试运行 完成商品服务 启动类 配置文件 实体类 Controller Service Mapper 测试运行 远程调用 需求 实现 1.定义RestTemplate 2.修改order-service中的OrderService 测试运行 Rest…

如何将网站提交百度收录完整SEO教程

百度收录是中文网站获取流量的重要渠道。本文以我的网站&#xff0c;www.mnxz.fun&#xff08;当然现在没啥流量&#xff09; 为例&#xff0c;详细讲解从提交收录到自动化维护的全流程。 一、百度收录提交方法 1. 验证网站所有权 1、登录百度搜索资源平台 2、选择「用户中心…