从入门到精通:详解Linux进程管理

前言

在这篇文章中,我将带领大家深入学习和理解Linux系统中的进程管理。无论你是初学者还是有一定经验的开发者,相信这篇文章都会对你有所帮助。我们将详细讲解冯诺依曼体系结构、操作系统概念、进程管理、进程调度、进程状态、环境变量、内存管理以及其他相关内容。

冯诺依曼体系结构

概述

冯诺依曼体系结构是现代计算机系统的基础。它由数学家兼物理学家冯·诺依曼于1945年提出,至今仍被广泛应用于各种计算机系统中。冯诺依曼体系结构的核心思想是将程序和数据存储在同一存储器中,并由中央处理器(CPU)按顺序读取和执行指令。通过这种方式,计算机系统能够以更高效、更灵活的方式运行各种应用程序。

组成部分

冯诺依曼体系结构由以下几个主要部分组成:

  1. 输入单元:包括键盘、鼠标、扫描仪等设备,用于向计算机输入数据和指令。
  2. 中央处理器(CPU):包含运算器和控制器,用于执行指令和处理数据。运算器负责执行各种算术和逻辑运算,控制器负责指挥和协调各个部分的工作。
  3. 内存:用于存储程序和数据。内存分为随机存取存储器(RAM)和只读存储器(ROM),RAM用于存储正在运行的程序和数据,ROM用于存储固化的程序和数据。
  4. 输出单元:包括显示器、打印机等设备,用于输出计算结果和信息。

数据流动过程

在冯诺依曼体系结构中,所有数据的输入和输出都必须经过内存。具体来说,数据流动过程如下:

  1. 用户通过输入单元(如键盘)输入数据。
  2. 数据被存储在内存中。
  3. CPU从内存中读取指令和数据,并进行处理。
  4. 处理结果被写入内存。
  5. 输出单元(如显示器)从内存中读取结果并显示给用户。

这种数据流动方式确保了计算机系统的统一和高效。以QQ聊天为例,当你登录QQ并与好友聊天时,输入的信息首先被存储在内存中,CPU从内存中读取并处理这些信息,处理后的信息再次存储在内存中,最后通过显示器输出。若你发送文件,文件数据也会经过相同的路径流动,确保信息传递的可靠性。

操作系统(Operating System)

概念

操作系统(OS)是管理计算机硬件和软件资源的系统软件,负责为用户提供一个良好的操作环境。操作系统的核心部分是内核,它负责进程管理、内存管理、文件管理和驱动管理等。此外,操作系统还包括一些其他程序,如函数库和Shell程序。操作系统的功能可以概括为两个方面:资源管理和用户接口。

设计目的

操作系统的设计目的是:

  1. 与硬件交互:管理计算机的所有硬件资源,如CPU、内存、磁盘和输入输出设备。操作系统通过设备驱动程序与硬件进行交互,确保硬件设备能够被正确使用。
  2. 提供执行环境:为用户程序(应用程序)提供一个良好的执行环境,使用户能够方便地开发和运行应用程序。操作系统提供了丰富的系统调用和库函数,简化了应用程序的开发过程。

定位

在计算机软硬件架构中,操作系统的定位是一款“管理”软件。它通过描述和组织被管理对象,实现对系统资源的有效管理。例如,操作系统通过使用结构体(struct)描述硬件资源,通过链表或其他高效数据结构组织这些资源,从而实现对资源的管理。

系统调用和库函数

操作系统通过系统调用向上层开发者暴露部分接口,供其使用。系统调用提供了基本的功能,而库函数对系统调用进行了封装,提供了更高层次的接口,方便用户进行二次开发。例如,文件操作的系统调用包括openreadwrite等,而C标准库中的fopenfreadfwrite等函数则对这些系统调用进行了封装,使得文件操作更加方便和易于理解。

进程(Process)

基本概念

进程是程序的一个执行实例,代表正在运行的程序。进程是操作系统资源分配的基本单位,负责管理CPU时间、内存和其他资源。在内核中,进程被描述为一个分配系统资源的实体。每个进程都有自己独立的地址空间、堆栈以及文件描述符表。

描述进程—PCB

进程信息存储在一个叫做进程控制块(PCB)的数据结构中。PCB包含了进程的所有属性,是操作系统管理进程的核心数据结构。在Linux操作系统中,PCB被实现为task_struct结构体。

task_struct内容分类

task_struct包含以下内容:

  1. 标示符:描述进程的唯一标示符,用于区分其他进程。
  2. 状态:任务状态、退出代码、退出信号等。
  3. 优先级:相对于其他进程的优先级。
  4. 程序计数器:程序中即将被执行的下一条指令的地址。
  5. 内存指针:包括程序代码和进程相关数据的指针,以及与其他进程共享的内存块的指针。
  6. 上下文数据:进程执行时处理器寄存器中的数据。
  7. I/O状态信息:包括显示的I/O请求、分配给进程的I/O设备和被进程使用的文件列表。
  8. 记账信息:可能包括处理器时间总和、使用的时钟数总和、时间限制、记账号等。
  9. 其他信息:其他与进程相关的信息。

组织进程

在Linux内核中,所有运行的进程都以task_struct链表的形式存在内核中。通过这种方式,操作系统可以高效地管理和调度进程。每个task_struct结构体都包含指向下一个进程的指针,这样所有进程就形成了一个双向链表,操作系统可以方便地遍历和管理这些进程。

查看进程

用户可以通过/proc文件系统查看进程的信息。例如,要获取PID为1的进程信息,可以查看/proc/1文件夹。此外,用户还可以使用topps等命令行工具获取进程信息。ps命令可以显示系统中所有正在运行的进程及其详细信息,而top命令则可以动态地显示系统资源的使用情况和进程状态。

示例代码

以下示例代码展示了如何使用ps命令查看系统中所有进程的信息:

ps -aux

该命令输出的信息包括进程ID、用户ID、CPU使用率、内存使用率、进程状态、命令名称等。

进程状态

进程的不同状态

在Linux内核中,进程可以处于以下几种状态:

  1. R(运行状态):表明进程正在运行或在运行队列中等待运行。
  2. S(睡眠状态):表明进程在等待事件完成,有时也称为可中断睡眠(interruptible sleep)。
  3. D(磁盘休眠状态):有时也称为不可中断睡眠状态(uninterruptible sleep),通常等待I/O操作完成。
  4. T(停止状态):进程被停止,可以通过发送SIGSTOP信号暂停进程,通过SIGCONT信号恢复运行。
  5. X(死亡状态):进程已经终止,不会出现在任务列表中。
  6. Z(僵尸状态):进程已经终止,但其退出状态还没有被父进程读取,保持在进程表中。

查看进程状态

用户可以通过pstop等命令查看进程状态。例如,使用ps aux命令可以查看系统中所有进程及其状态。以下是ps aux命令的示例输出:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1  22568  1196 ?        Ss   10:00   0:01 /sbin/init
root       672  0.00.3  37644  3312 ?        Ss   10:00   0:02 /usr/sbin/sshd

在输出信息中,STAT字段表示进程的状态。例如,Ss表示进程处于睡眠状态且是会话领导进程,R表示进程正在运行。

示例代码

以下示例代码展示了如何使用top命令动态查看系统资源使用情况和进程状态:

top

top命令界面中,用户可以看到系统的总体资源使用情况,包括CPU、内存和交换分区的使用率,以及所有正在运行的进程的信息。用户可以通过按k键终止进程,通过按r键调整进程的优先级。

僵尸进程(Zombie Process)

概念与形成原因

僵尸进程是已经终止但其退出状态尚未被父进程读取的进程。当子进程退出后,父进程需要通过waitwaitpid系统调用读取子进程的退出状态,否则子进程会保持在僵尸状态。僵尸进程的出现是由于父进程没有及时回收子进程的资源,导致子进程的信息无法从系统中清除。

危害

僵尸进程会占用系统资源,特别是进程控制块(PCB)中的内存资源。如果大量僵尸进程存在,会导致系统资源枯竭,影响系统性能和稳定性。此外,僵尸进程的存在还可能影响系统的正常运行和维护,因为系统管理员可能会误以为这些进程仍在运行。

解决方法

通过在父进程中使用waitwaitpid函数可以避免僵尸进程。例如,父进程可以在子进程终止时调用wait函数读取子进程的退出状态,从而释放其占用的资源。以下是一个示例代码,展示了如何在父进程中使用wait函数回收子进程的资源:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {printf("Child process\n");sleep(2);exit(0);} else {printf("Parent process\n");wait(NULL);  // 回收子进程资源printf("Child process terminated\n");}return 0;
}

在这个示例中,父进程通过调用wait函数等待子进程终止,并回收其资源,避免了僵尸进程的产生。

孤儿进程(Orphan Process)

概念与形成原因

孤儿进程是其父进程已经终止,但子进程仍在运行的进程。孤儿进程会被系统的1号进程(init进程)收养,并由init进程负责回收资源。孤儿进程的产生通常是由于父进程异常终止或故意终止,而子进程仍需要继续执行其任务。

危害与处理

孤儿进程不会对系统造成危害,因为它们会被init进程收养并管理。操作系统通过这种机制确保所有进程都能被正确管理和回收。以下是一个示例代码,展示了孤儿进程的形成过程:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程sleep(5);  // 保证子进程在父进程退出后继续运行printf("Child process: parent PID = %d\n", getppid());exit(0);} else {// 父进程printf("Parent process\n");exit(0);  // 父进程立即退出}return 0;
}

在这个示例中,父进程立即退出,子进程在父进程退出后继续运行,此时子进程成为孤儿进程,并被init进程收养。通过在子进程中打印父进程的PID,可以验证子进程在成为孤儿进程后,其父进程PID会变为1(init进程的PID)。

进程优先级

基本概念

进程优先级决定了进程获得CPU时间的先后顺序。优先级高的进程优先获得CPU资源,从而更快地执行。Linux系统中,用户可以通过调整进程的nice值来改变进程的优先级。nice值的范围为-20到19,值越小优先级越高。

查看进程优先级

用户可以使用ps -l命令查看进程的优先级和nice值。例如:

ps -l

输出信息中包含以下重要字段:

  • UID:执行者的身份。
  • PID:进程ID。
  • PPID:父进程ID。
  • PRI:进程的优先级,值越小优先级越高。
  • NI:进程的nice值。

调整进程优先级

用户可以使用nice命令启动一个具有特定优先级的进程,也可以使用renice命令调整已有进程的优先级。例如:

nice -n 10 ./myprogram
renice -n -5 -p 12345

以下是一个示例代码,展示了如何使用nice命令启动一个具有特定优先级的进程:

nice -n -10 ./myprogram

在这个示例中,myprogram程序将以较高的优先级运行,因为其nice值被设置为-10。

示例代码

以下是一个完整的示例代码,展示了如何调整进程的优先级并查看其效果:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程int ret = nice(-10);  // 设置较高优先级if (ret == -1) {perror("nice");}printf("Child process: nice value = %d\n", ret);while (1) {// 子进程持续运行,观察优先级的影响}} else {// 父进程printf("Parent process\n");while (1) {// 父进程持续运行,观察优先级的影响}}return 0;
}

运行该程序后,可以使用ps -l命令查看子进程和父进程的优先级和nice值,并观察其在系统中的表现。

环境变量

基本概念

环境变量是操作系统中用来指定操作系统运行环境的一些参数。在编写C/C++代码时,编译器可以通过环境变量查找所需的动态或静态库。环境变量通常具有全局特性,可以影响系统中的所有进程。

常见环境变量

  • PATH:指定命令的搜索路径。当用户在终端中输入命令时,系统会在PATH指定的目录中搜索可执行文件。
  • HOME:指定用户的主工作目录,即用户登录到系统后的默认目录。
  • SHELL:指定当前Shell的路径,通常是/bin/bash

查看和设置环境变量

用户可以使用以下命令查看和设置环境变量:

echo $PATH  # 查看PATH环境变量
export MYVAR="Hello, World!"  # 设置环境变量
unset MYVAR  # 清除环境变量
env  # 显示所有环境变量

示例代码

以下是一个示例代码,展示了如何在程序中获取和设置环境变量:

#include <stdio.h>
#include <stdlib.h>int main() {char *path = getenv("PATH");if (path) {printf("PATH: %s\n", path);}setenv("MYVAR", "Hello, World!", 1);printf("MYVAR: %s\n", getenv("MYVAR"));return 0;
}

在这个示例中,程序首先获取并打印PATH环境变量的值,然后设置一个新的环境变量MYVAR并打印其值。

环境变量的全局属性

环境变量通常具有全局属性,可以被子进程继承。例如,通过export命令设置的环境变量可以在子进程

中访问:

export MYVAR="Hello, World!"
./myprogram

子进程运行时可以访问并打印MYVAR的值。

示例代码

以下是一个示例代码,展示了环境变量的全局属性:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process: MYVAR = %s\n", getenv("MYVAR"));} else {// 父进程printf("Parent process\n");setenv("MYVAR", "Hello from parent", 1);wait(NULL);  // 等待子进程终止}return 0;
}

在这个示例中,父进程设置了一个环境变量MYVAR,子进程继承并打印了该环境变量的值。

进程地址空间

基本概念

进程地址空间是操作系统为每个进程分配的虚拟内存空间。在32位系统中,进程地址空间通常为4GB。地址空间分为用户空间和内核空间,用户空间用于存放用户程序和数据,内核空间用于存放操作系统内核和内核数据。

虚拟地址与物理地址

虚拟地址是用户程序看到的地址,而物理地址是内存中的实际地址。操作系统通过页表将虚拟地址映射到物理地址,确保程序在运行时能够正确访问内存。

进程地址空间布局

进程地址空间通常包含以下几部分:

  1. 代码段:存放程序代码。
  2. 数据段:存放全局变量和静态变量。
  3. :用于动态内存分配。
  4. :用于函数调用时存放局部变量和返回地址。

示例代码

以下是一个简单的示例,展示了进程地址空间的使用:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int global_var = 0;int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {  // 子进程global_var = 100;printf("Child: %d, %p\n", global_var, &global_var);} else {  // 父进程sleep(1);printf("Parent: %d, %p\n", global_var, &global_var);}return 0;
}

运行该程序会显示父子进程中变量地址相同但值不同的现象,说明虚拟地址相同但物理地址不同。通过这个示例,可以理解虚拟地址和物理地址的区别,以及进程地址空间的布局。

进程调度

调度算法

Linux内核使用多种调度算法来管理进程的执行顺序。常见的调度算法包括先来先服务(FCFS)、最短作业优先(SJF)、优先级调度(Priority Scheduling)和时间片轮转(Round Robin)。这些算法各有优缺点,适用于不同的场景和需求。

O(1)调度算法

Linux 2.6内核采用了O(1)调度算法,该算法确保调度操作的时间复杂度为常数,不随进程数量增加而增加。O(1)调度算法使用两个队列来管理进程:活动队列和过期队列。活动队列存放正在运行或准备运行的进程,过期队列存放时间片已耗尽的进程。

活动队列与过期队列

  • 活动队列:存放正在运行或准备运行的进程。调度器从活动队列中选择优先级最高的进程进行调度。
  • 过期队列:存放时间片已耗尽的进程。当活动队列中的进程全部运行完毕后,调度器会将活动队列和过期队列交换,重新开始调度。

示例代码

以下是一个示例代码,展示了如何在Linux内核中实现进程调度:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {pid_t pid1, pid2;pid1 = fork();if (pid1 == 0) {// 子进程1while (1) {printf("Child 1 running\n");sleep(1);}} else {pid2 = fork();if (pid2 == 0) {// 子进程2while (1) {printf("Child 2 running\n");sleep(1);}} else {// 父进程while (1) {printf("Parent running\n");sleep(1);}}}return 0;
}

运行该程序后,可以观察到父进程和两个子进程轮流执行,展示了时间片轮转调度的效果。

环境变量的组织方式

环境表

每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以\0结尾的环境字符串。

获取和设置环境变量

用户可以通过系统调用或库函数获取和设置环境变量。例如,使用getenvsetenv函数可以访问特定的环境变量:

#include <stdio.h>
#include <stdlib.h>int main() {char *path = getenv("PATH");if (path) {printf("PATH: %s\n", path);}setenv("MYVAR", "Hello, World!", 1);printf("MYVAR: %s\n", getenv("MYVAR"));return 0;
}

在这个示例中,程序首先获取并打印PATH环境变量的值,然后设置一个新的环境变量MYVAR并打印其值。

环境变量的全局属性

环境变量通常具有全局属性,可以被子进程继承。例如,通过export命令设置的环境变量可以在子进程中访问:

export MYVAR="Hello, World!"
./myprogram

子进程运行时可以访问并打印MYVAR的值。

示例代码

以下是一个示例代码,展示了环境变量的全局属性:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {// 子进程printf("Child process: MYVAR = %s\n", getenv("MYVAR"));} else {// 父进程printf("Parent process\n");setenv("MYVAR", "Hello from parent", 1);wait(NULL);  // 等待子进程终止}return 0;
}

在这个示例中,父进程设置了一个环境变量MYVAR,子进程继承并打印了该环境变量的值。

进程内存映像

程序地址空间回顾

程序地址空间通常包含代码段、数据段、堆和栈。在32位系统中,地址空间分为用户空间和内核空间。用户空间用于存放用户程序和数据,内核空间用于存放操作系统内核和内核数据。

虚拟地址与物理地址

虚拟地址是用户程序看到的地址,而物理地址是内存中的实际地址。操作系统通过页表将虚拟地址映射到物理地址,确保程序在运行时能够正确访问内存。

进程地址空间布局

进程地址空间通常包含以下几部分:

  1. 代码段:存放程序代码。
  2. 数据段:存放全局变量和静态变量。
  3. :用于动态内存分配。
  4. :用于函数调用时存放局部变量和返回地址。

示例代码

以下是一个简单的示例,展示了进程地址空间的使用:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int global_var = 0;int main() {pid_t pid = fork();if (pid < 0) {perror("fork");return 1;} else if (pid == 0) {  // 子进程global_var = 100;printf("Child: %d, %p\n", global_var, &global_var);} else {  // 父进程sleep(1);printf("Parent: %d, %p\n", global_var, &global_var);}return 0;
}

运行该程序会显示父子进程中变量地址

相同但值不同的现象,说明虚拟地址相同但物理地址不同。通过这个示例,可以理解虚拟地址和物理地址的区别,以及进程地址空间的布局。

总结

通过本文的学习,我们详细介绍了Linux系统中的进程管理。从冯诺依曼体系结构、操作系统概念、进程管理、进程调度、进程状态、环境变量、内存管理等多个方面进行了深入讲解。掌握这些知识,可以帮助我们更高效地管理和使用Linux系统。希望这篇文章对大家有所帮助。如果有任何问题或建议,欢迎在评论区留言与我交流。感谢大家的阅读!

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

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

相关文章

C语言之函数和函数库以及自己制作静态动态链接库并使用

一&#xff1a;函数的本质 1&#xff1a;C语言为什么会有函数 &#xff08;1&#xff09;整个程序分为多个源文件&#xff0c;一个文件分为多个函数&#xff0c;一个函数分成多个语句&#xff0c;这就是整个程序的组织形式。这样的组织好处在于&#xff1a;分化问题、、便于程序…

分布式版本控制工具 git

git 是什么 分布式版本控制工具。github 是代码托管平台。 git 有什么用 保存文件的所有修改记录。使用版本号&#xff08;sha1 哈希值&#xff09; 进行区分。随时可浏览历史版本记录。可还原到历史指定版本。对比不同版本的文件差异。 为什么要使用 git 多人协作开发一个大…

SQL 优化

SQL 优化是指通过各种手段提高 SQL 查询的执行效率,减少资源消耗,提高数据库的整体性能。以下是一些详细的 SQL 优化方法,包括索引优化、查询优化、数据库设计优化等。 1. 索引优化 创建适当的索引: 单列索引:在查询中频繁使用的单个列上创建索引。多列索引(复合索引):…

STM32手写超频到128M函数

今天学习了野火的STM32教程学会了如何设置STM32的时钟频率&#xff0c;步骤比较详细&#xff0c;也很容易理解&#xff0c;就是视频教程不能跳着看&#xff0c;只能一节节的看&#xff0c;不然会知识不连贯&#xff0c;造成有些知识不理解&#xff0c;连续着看还是没有什么难度…

docker-file 网络

docker挂载 1.绑定挂载&#xff08;Bind Mounts&#xff09;&#xff1a;绑定挂载是将主机上的文件或目录挂载到容器中。 docker run -v /host/path:/container/path image_name 2.卷挂载&#xff08;Volume Mounts&#xff09;&#xff1a;卷挂载将 Docker 数据卷挂载到容器中…

【CTF Web】CTFShow web4 Writeup(SQL注入+PHP+字符型注入)

web4 1 管理员阿呆又失败了&#xff0c;这次一定要堵住漏洞 解法 注意到&#xff1a; <!-- flag in id 1000 -->拦截很多种字符&#xff0c;连 select 也不给用了。 if(preg_match("/or|\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\|select/i",$id)){die(&q…

yolov8推理由avi改为mp4

修改\ultralytics-main\ultralytics\engine\predictor.py&#xff0c;即可 # Ultralytics YOLO &#x1f680;, AGPL-3.0 license """ Run prediction on images, videos, directories, globs, YouTube, webcam, streams, etc.Usage - sources:$ yolo modepred…

Android开发-Android开发中的TCP与UDP通信策略的实现

Android 开发中的 TCP 与 UDP 通信策略的实现 1. 前言2. 准备工作3. Kotlin 中 TCP 通信实现客户端代码示例&#xff1a;服务器代码示例&#xff1a; 4. Kotlin 中 UDP 通信实现客户端代码示例&#xff1a;服务器代码示例&#xff1a; 5. TCP 与 UDP 应用场景分析TCP 实现可靠传…

搭建访问阿里云百炼大模型环境

最近这波大降价&#xff0c;还有限时免费&#xff0c;还不赶快试试在线大模型&#xff1f;下面整理访问百炼平台的千问模型方法。 创建RAM子账号并授权 创建RAM子账号 1. “访问控制RAM”入口&#xff08;控制台URL&#xff09; 然后点击进入“RAM管理控制台” 2. 添加用户 …

vue 区分多环境打包

需求&#xff1a;区分不同的环境&#xff08;测试、正式环境&#xff09;&#xff0c;接口文档地址不同&#xff1b; 配置步骤&#xff1a; 1、在根目录下面新建 .env.xxx 文件&#xff08;xxx 根据环境不同配置&#xff09; 文件中一定要配置的参数项为&#xff1a;NODE_ENV…

【Python搞定车载自动化测试】——Python实现CAN总线Bootloader刷写(含Python源码)

系列文章目录 【Python搞定车载自动化测试】系列文章目录汇总 文章目录 系列文章目录&#x1f4af;&#x1f4af;&#x1f4af; 前言&#x1f4af;&#x1f4af;&#x1f4af;一、环境搭建1.软件环境2.硬件环境 二、目录结构三、源码展示1.诊断基础函数方法2.诊断业务函数方法…

python 火焰检测

在日常生活,总是离不开火,有时候我们需要预防火灾发生,但是我们又不可能一直盯着,这时候我们就需要一款程序帮我们盯着,一旦发生火灾从而告知我们,今天就带大家编写这么一款应用。 安装需要的库 pip install opencv-python 代码实现 import cv2 # Library for…

qmt量化教程4----订阅全推数据

文章链接 qmt量化教程4----订阅全推数据 (qq.com) 上次写了订阅单股数据的教程 量化教程3---miniqmt当作第三方库设置&#xff0c;提供源代码 全推就主动推送&#xff0c;当行情有变化就会触发回调函数&#xff0c;推送实时数据&#xff0c;可以理解为数据驱动类型&#xff0…

mysql中使用 mysqldump 实现跨机器备份|数据同步

1.如果同步数据库&#xff0c;必须先创建数据库&#xff1a; mysqldump -h 192.168.1.10 --lock-tablesfalse -uroot -proot db_name | mysql -h127.0.0.1 -uroot -proot db_name2.过滤掉不想要的表(没试过&#xff0c;但是试过转为sql文件的) mysqldump -h 192.168.1.10 --…

vs2019 c++ 函数的返回值是对象的值传递时候,将调用对象的移动构造函数

以前倒没有注意过这个问题。但编译器这么处理也符合移动构造的语义。因为本来函数体内的变量也要离开作用域被销毁回收了。测试如下&#xff1a; 谢谢

实现信号发生控制

1. 信号发生器的基本原理 信号发生器是一种能够产生特定波形和频率的电子设备&#xff0c;常用于模拟信号的产生和测试。 信号发生器的基本原理 信号发生器的工作原理基于不同的技术&#xff0c;但最常见的类型包括模拟信号发生器和数字信号发生器&#xff08;DDS&#xff0…

[SCTF2019]babyre

打开看看还是有花指令 解除后首先pass1是解maze&#xff0c;好像又是三维的 x是25&#xff0c;也就是向下跳五层,注意是立体的 得到 passwd1&#xff1a; ddwwxxssxaxwwaasasyywwdd 接着往下看 有一个加密函数IDA逆向常用宏定义_lodword-CSDN博客 unsigned __int64 __fastca…

primeflex样式库笔记 Display相关的案例

回顾 宽度设置的基本总结 w-full&#xff1a;表示widtdh&#xff1a;100%&#xff1b;占满父容器的宽度。 w-screen&#xff1a;表示占满整个屏幕的宽度。 w-1到w-12&#xff0c;是按百分比划分宽度&#xff0c;数字越大&#xff0c;占据的比例就越大。 w-1rem到w-30rem&…

Oracle的安装以及一些相关问题

系列文章目录 Oracle的安装以及一些相关问题 文章目录 系列文章目录前言一、Oracle的安装二、常用命令三、误删dbf四、PLSQL乱码五、oracle更换数据库字符集总结 前言 一段时间没更新&#xff0c;主要最近一直在找工作&#xff0c;最终还是顺着春招找到工作了&#xff0c;现在…

美信時代監控易:堆疊交換機的監控與配置管理策略

隨著企業數字化轉型的加速&#xff0c;網絡架構的複雜性日益提升&#xff0c;堆疊交換機作為高可靠性、靈活擴展性的解決方案&#xff0c;在網絡基礎設施中扮演著至關重要的角色。然而&#xff0c;如何確保堆疊交換機的穩定運行&#xff0c;實現高效監控與配置管理&#xff0c;…