多进程编程:原理、技术与应用

news2024/12/23 18:32:41

title: 多进程编程:原理、技术与应用
date: 2024/4/26 12:14:47
updated: 2024/4/26 12:14:47
categories:

  • 后端开发

tags:

  • 多进程
  • 并发编程
  • 网络服务
  • 分布式系统
  • 任务处理
  • 进程池
  • 线程对比

在这里插入图片描述

第一章:进程与线程

进程与线程的概念及区别:
  • 进程:进程是操作系统中的一个程序执行实例。每个进程都有自己独立的内存空间,包括代码、数据、堆栈等。进程之间是相互独立的,彼此不会直接影响。进程是系统进行资源分配和调度的基本单位。

  • 线程:线程是进程中的一个执行单元,一个进程可以包含多个线程。同一进程中的多个线程共享相同的内存空间,包括代码段、数据段等。线程之间可以直接进行通信,共享数据。线程是 CPU 调度的基本单位。

  • 区别

    • 进程拥有独立的内存空间,而线程共享相同的内存空间。
    • 进程之间的切换开销比线程大,因为进程切换需要切换内存空间,而线程切换只需切换上下文。
    • 进程之间通信需要额外的 IPC(进程间通信),而线程之间可以直接共享数据。
    • 进程更安全稳定,一个进程崩溃不会影响其他进程,而线程共享内存,一个线程崩溃可能导致整个进程崩溃。
进程控制块(PCB)和线程控制块(TCB):
  • 进程控制块(PCB) :PCB是操作系统中用于管理进程的数据结构。每个进程都有一个对应的 PCB,用于存储进程的状态信息、程序计数器、内存指针、文件描述符等。操作系统通过 PCB 来管理和调度进程。
  • 线程控制块(TCB) :TCB是操作系统中用于管理线程的数据结构。每个线程也有一个对应的 TCB,用于存储线程的状态信息、栈指针、寄存器值等。操作系统通过 TCB 来管理和调度线程。
进程状态转换图:

进程在其生命周期中会经历不同的状态,常见的进程状态包括:

  • 创建态:进程正在被创建,分配必要的资源。
  • 就绪态:进程已经准备好运行,等待被调度执行。
  • 运行态:进程正在 CPU 上执行指令。
  • 阻塞态:进程暂时无法执行,通常是在等待某个事件发生。
  • 终止态:进程执行完毕或被终止,释放资源。

进程在不同状态之间的转换可以用进程状态转换图来表示,图中展示了进程在不同状态之间的转换关系及触发条件。操作系统根据进程状态的变化来进行进程调度和管理,确保系统资源的合理利用和进程的正常运行。

第二章:进程间通信(IPC)

IPC的基本概念和作用:
  • IPC(Inter-Process Communication) :进程间通信是指在不同进程之间传递和共享数据的机制。进程间通信允许不同的进程在运行时相互交换信息、协调操作,从而实现协作和共享资源。

  • 作用

    • 实现进程间数据传输和共享。
    • 实现进程间同步和互斥,确保进程之间的顺序和数据一致性。
    • 提高系统的灵活性和效率,允许不同进程之间独立运行并协同工作。
管道(Pipe):
  • 匿名管道:匿名管道是一种单向通信机制,用于在父子进程或兄弟进程之间传递数据。匿名管道只能用于具有亲缘关系的进程间通信,数据只能单向流动。
  • 命名管道:命名管道是一种特殊类型的文件,允许无关的进程之间进行通信。命名管道可以通过文件系统路径访问,不受进程亲缘关系限制。
信号量(Semaphore):
  • 二进制信号量:二进制信号量只有两个取值(0和1),用于实现进程间的互斥和同步。通常用于解决生产者-消费者问题等场景。
  • 计数信号量:计数信号量可以取多个取值,用于控制多个进程对共享资源的访问。计数信号量可以用于控制资源的数量和访问权限。
消息队列(Message Queue):
  • 消息队列:消息队列是一种进程间通信的方式,允许进程通过发送和接收消息来进行通信。消息队列可以实现不同进程之间的异步通信,提高系统的灵活性和效率。
共享内存(Shared Memory):
  • 共享内存:共享内存允许多个进程共享同一块内存区域,从而实现高效的数据共享。共享内存是最快的 IPC 方式,但需要进程之间进行同步和互斥控制,以避免数据一致性问题。
套接字(Socket):
  • 套接字:套接字是一种通用的进程间通信机制,可用于不同主机之间的通信。套接字可以实现进程间的网络通信,包括 TCP 和 UDP 通信。套接字提供了一种灵活且强大的通信方式,广泛应用于网络编程和分布式系统中。

第二部分:进程同步与通信

第三章:进程同步
同步与异步:
  • 同步:同步是指在进行某个操作时,必须等待前一个操作完成后才能进行下一个操作。同步操作可以保证数据的一致性和顺序性,但可能会造成程序的阻塞。
  • 异步:异步是指不需要等待前一个操作完成,可以同时进行多个操作。异步操作可以提高程序的响应速度和并发性,但需要额外的机制来处理数据的一致性和顺序性。
临界区(Critical Section):
  • 临界区:临界区是指一段代码或代码块,同一时刻只允许一个进程访问。进程在进入临界区前需要获取同步对象(如互斥量、信号量),以确保临界区的互斥访问。
互斥量(Mutex):
  • 互斥量:互斥量是一种用于实现进程间互斥访问的同步对象。只有拥有互斥量的进程才能进入临界区,其他进程需要等待。互斥量通常用于保护临界区,防止多个进程同时访问共享资源。
信号量(Semaphore):
  • 信号量:信号量是一种用于控制多个进程对共享资源访问的同步对象。信号量可以实现进程间的同步和互斥,允许多个进程同时访问共享资源,但需要控制访问的数量和顺序。
事件(Event):
  • 事件:事件是一种用于进程间通信和同步的同步对象。事件可以有信号和无信号两种状态,用于通知进程事件的发生。事件可以用于进程间的通知、等待和唤醒操作,实现进程的同步和协作。
第四章:进程通信模式
单工通信:
  • 单工通信:单工通信是指数据只能单向传输的通信模式。在单工通信中,通信的一方只能发送数据,而另一方只能接收数据。这种通信模式类似于广播,但通信的双方不对等,不能同时进行数据传输和接收。
半双工通信:
  • 半双工通信:半双工通信是指数据可以双向传输但不能同时进行的通信模式。在半双工通信中,通信的双方可以交替地发送和接收数据,但不能同时进行发送和接收。这种通信模式类似于对讲机,通信的双方可以轮流发言。
全双工通信:
  • 全双工通信:全双工通信是指数据可以双向传输且可以同时进行的通信模式。在全双工通信中,通信的双方可以同时进行发送和接收数据,实现实时的双向通信。这种通信模式类似于电话通话,通信的双方可以同时交流信息。
客户端-服务器通信模式:
  • 客户端-服务器通信模式:客户端-服务器通信模式是一种常见的网络通信模式,用于实现客户端和服务器之间的数据交互。在这种通信模式中,客户端向服务器发送请求,服务器处理请求并返回相应的结果给客户端。这种通信模式可以实现双向的数据传输和交互,通常用于构建分布式系统和网络应用。

第三部分:高级主题与实践应用

第五章:进程池与并发控制
进程池的概念和设计:
  • 进程池:进程池是一种管理和复用进程的技术,用于提高系统的性能和资源利用率。进程池在系统启动时创建一定数量的进程,并将它们保存在一个池中,当需要处理任务时,可以从池中获取空闲的进程来执行任务,执行完任务后再将进程放回池中等待下一个任务。这种复用进程的方式减少了频繁创建和销毁进程的开销,提高了系统的效率。
并发控制的算法与技术:
  • 并发控制:并发控制是指在多进程或多线程环境下管理和协调进程或线程之间的并发操作,以确保数据的一致性和正确性。常见的并发控制算法和技术包括锁机制、信号量、条件变量、读写锁、原子操作等。这些技术可以用于控制进程或线程的访问顺序、共享资源的争用情况,避免数据竞争和死锁等并发问题。
高级进程池应用场景:
  • 高级进程池应用场景

    1. Web 服务器:在Web服务器中使用进程池可以提高并发请求的处理能力,减少响应时间,提升用户体验。
    2. 数据库连接池:数据库连接池是一种特殊的进程池,用于管理数据库连接,提高数据库访问的效率和性能。
    3. 计算密集型任务:对于需要大量计算的任务,可以使用进程池来并行执行任务,加快任务完成的速度。
    4. 爬虫程序:爬虫程序通常需要并发地抓取网页数据,使用进程池可以提高爬虫的效率和速度。
    5. 消息队列消费者:消息队列中的消费者可以使用进程池来并发地处理消息,实现高效的消息处理系统。

这些高级进程池应用场景可以充分利用进程池的优势,提高系统的性能和并发处理能力。

第六章:多进程调试与性能优化
多进程调试工具介绍:
  • 多进程调试工具:多进程调试工具是用于调试多进程程序的工具,可以帮助开发者定位并修复多进程程序中的问题。常见的多进程调试工具包括GDB、Strace、Ltrace等。这些工具可以提供进程的运行状态、调用栈、内存使用情况等信息,帮助开发者理解程序的运行逻辑和问题所在。
性能分析与优化策略:
  • 性能分析与优化策略:性能分析与优化是指通过分析程序的运行状况,找出性能瓶颈和问题,优化程序的资源使用和执行效率。常见的性能分析与优化策略包括性能监测、内存分析、CPU分析、I/O分析等。这些策略可以帮助开发者了解程序的性能状况,找到性能优化的方向和方法。
实战案例分析:
  • 实战案例分析:通过实战案例分析,可以更好地理解多进程调试和性能优化的方法和技巧。例如,可以通过分析一个多进程Web服务器的性能问题,找出瓶颈所在,采用适当的优化策略,提高服务器的性能和并发处理能力。这样的实战案例分析可以帮助开发者更好地理解多进程程序的运行机制和优化方法。
代码示例:

以下是一个使用GDB调试多进程程序的示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {
    pid_t pid = fork();
    if (pid == 0) { // 子进程代码
        for (int i = 0; i < 1000000; i++) {
            printf("%d\n", i);
        }
        return 0;
    } else {
        // 父进程代码
        pid_t status;
        waitpid(pid, &status, 0);
        if (WIFEXITED(status)) {
            printf("子进程退出,状态码: %d\n", WEXITSTATUS(status));
        } else if (WIFSIGNALED(status)) {
            printf("子进程被信号中断,信号号: %d\n", WTERMSIG(status));
        } else {
            printf("子进程未正常结束\n");
        }
    }
    return 0;
}

在这个例子中,父进程创建了一个子进程,子进程执行一个耗时的操作。父进程通过 waitpid 等待子进程结束,并根据返回的状态码判断子进程的退出情况。

要使用 GDB 进行调试,你需要编译并运行程序,然后在GDB中附加到进程:

gdb your_program
(gdb) run

在GDB中,你可以设置断点、查看变量值、单步执行等,帮助你定位和解决问题。

总结:

多进程调试和性能优化是复杂而重要的任务,需要开发者具备一定的理论知识和实践经验。通过学习和实践,你可以有效地提高程序的稳定性和性能。如果你在实际开发中遇到具体问题,记得提供详细的问题描述,我会更具体地帮助你解决问题。

第七章:多进程编程实战

多进程编程在网络服务器开发、分布式系统设计和多进程并发任务处理中有着广泛的应用。在这一章中,我们将介绍多进程编程在这些领域的应用,并通过实例代码展示如何使用多进程编程技术实现这些应用。

7.1 网络服务器开发

网络服务器是一个典型的多进程编程应用。在网络服务器开发中,我们通常使用多进程技术来实现并发处理多个客户端请求,从而提高服务器的性能和吞吐量。下面是一个简单的网络服务器示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define PORT 8080

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);

    // 创建socket
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    // 设置socket选项
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    // 绑定socket
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    // 监听socket
    if (listen(server_fd, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    while (1) {
        // 接收连接
        if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
            perror("accept");
            exit(EXIT_FAILURE);
        }

        // 创建子进程处理连接
        if (fork() == 0) {
            char buffer[1024] = {0};
            int valread;
            valread = read(new_socket, buffer, 1024);
            printf("Client message: %s\n", buffer);
            send(new_socket, "Server received your message", strlen("Server received your message"), 0);
            close(new_socket);
            exit(0);
        } else {
            close(new_socket);
        }
    }

    return 0;
}

在上面的代码中,我们创建了一个简单的网络服务器,通过socket、bind、listen和accept函数来建立服务器,然后使用fork函数创建子进程来处理客户端的连接请求。每个子进程负责处理一个客户端连接,接收客户端发送的消息并回复消息,然后关闭连接。

7.2 分布式系统设计

在分布式系统设计中,多进程编程可以用来实现分布式系统中的各个节点之间的通信和协作。通过多进程技术,可以实现分布式系统中的任务分发、数据同步、负载均衡等功能。下面是一个简单的分布式系统设计示例代码:

from multiprocessing import Process, Queue

def worker(queue):
    while True:
        task = queue.get()
        if task == 'exit':
            break
        print(f"Processing task: {task}")

if __name__ == '__main__':
    tasks = ['task1', 'task2', 'task3']

    queue = Queue()
    processes = []

    for task in tasks:
        queue.put(task)

    for _ in range(3):
        process = Process(target=worker, args=(queue,))
        process.start()
        processes.append(process)

    for process in processes:
        process.join()

    for _ in range(3):
        queue.put('exit')

在上面的Python代码中,我们通过multiprocessing模块创建了一个简单的分布式系统,其中包括一个任务队列和多个工作进程。每个工作进程从任务队列中获取任务并处理,直到接收到退出信号。通过这种方式,可以实现分布式系统中任务的并发处理。

7.3 多进程并发任务处理

一个覆盖广泛主题工具的高效在线平台

多进程并发任务处理是指通过多个进程同时处理多个任务,以提高系统的效率和性能。在这种场景下,每个进程负责处理一个或多个任务,通过并发执行来加速任务处理过程。下面是一个简单的多进程并发任务处理示例代码:

from multiprocessing import Pool

def process_task(task):
    print(f"Processing task: {task}")

if __name__ == '__main__':
    tasks = ['task1', 'task2', 'task3']

    with Pool(processes=3) as pool:
        pool.map(process_task, tasks)

在上面的Python代码中,我们使用multiprocessing模块的Pool类来创建一个进程池,然后通过map函数将多个任务分发给进程池中的进程并发处理。这样可以有效利用多核处理器的优势,加速任务处理过程。

通过以上示例,我们可以看到多进程编程在网络服务器开发、分布式系统设计和多进程并发任务处理中的应用,能够提高系统的并发能力和性能。希望这些示例能帮助您更好地理解多进程编程在实际应用中的作用和实现方式。

import multiprocessing

def worker(num):
    """thread worker function"""
    print('Worker:', num)
    return

if __name__ == '__main__':
    jobs = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        jobs.append(p)
        p.start()

在上面的Python代码中,我们创建了一个简单的多进程程序,通过multiprocessing模块创建了5个进程,并将worker函数作为每个进程的目标函数。每个进程负责执行worker函数,并传入一个唯一的数字作为参数。通过这种方式,我们可以实现多进程并发执行任务。

7.4 多进程与多线程

在实际应用中,多进程与多线程都可以实现并发执行任务,但它们之间有一些区别和优缺点。

多进程的优点是:

  • 每个进程都有自己的地址空间,可以避免变量共享导致的数据一致性问题。
  • 每个进程都可以利用多核处理器的优势,提高系统的并发能力和性能。

多进程的缺点是:

  • 每个进程都需要占用系统资源,包括内存和CPU时间,因此进程的数量受到系统资源的限制。
  • 进程之间的通信和同步较为复杂,需要使用IPC(Inter-Process Communication)机制,如管道、信号、共享内存等。

多线程的优点是:

  • 线程比进程更加轻量级,可以创建大量的线程,不会占用太多系统资源。
  • 线程之间可以共享数据,因此可以方便地实现数据共享和通信。

多线程的缺点是:

  • 线程之间共享地址空间,因此可能导致变量共享导致的数据一致性问题。
  • 线程的并发执行可能导致线程安全问题

Python中的全局解释器锁(GIL)限制了多线程并发执行时只有一个线程可以执行Python字节码,因此多线程无法充分利用多核处理器的优势。

在选择多进程还是多线程时,可以根据具体的应用场景和需求来决定:

  • 如果任务是CPU密集型的,即需要大量的计算和处理,推荐使用多进程,可以充分利用多核处理器的优势。
  • 如果任务是I/O密集型的,即需要大量的I/O操作(如文件读写、网络请求等),推荐使用多线程,可以避免I/O阻塞,提高程序的响应速度。

总之,多进程和多线程都是实现并发编程的有效方式,开发者可以根据具体需求选择合适的方式来实现并发任务。在实际应用中,也可以将多进程和多线程结合起来使用,充分发挥它们各自的优势,实现高效的并发编程。

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

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

相关文章

四信智能化感知与控制方案,助推灌区续建配套与现代化改造建设

“十四五”明确提到推进大中型灌区节水改造和精细化管理&#xff0c;建设节水灌溉骨干工程&#xff0c;同步推进水价综合改革。 灌区是保障国家粮食安全的重要基础性设施&#xff0c;是实施乡村振兴战略的水利支撑。灌区续建配套与现代化改造是实施乡村振兴战略一项重要任务。为…

el-tab面板添加折叠按钮方法

折叠后 <template><div class"page-type-left-wrap"><div class"page-type-left-wrap-info nav-link" :class"{ leftCollapse }"><el-tabs v-model"activeName" class"page-tabs" tab-change"han…

Git系列:Refs与Reflog

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

【经典算法】LeetCode104二叉树的最大深度(Java/C/Python3实现含注释说明,Easy)

目录 题目描述思路及实现方式一&#xff1a;递归思路代码实现Java版本C语言版本Python3版本Go语言版本 复杂度分析 方式二&#xff1a;广度优先搜索(BFS)思路代码实现Java版本C语言版本Python3版本 复杂度分析 总结相似题目 标签(题目类型)&#xff1a;树、深度优先搜索(DFS)、…

B站无限评论暴力截留协议及教程

B站无限评论暴力截留协议及教程 B站无限评论暴力截留协议及教程&#xff0c;需要抓CK &#xff0c;教程里面有讲如何抓取 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x 提取码&#xff1a;0b8x

PHP 错误 Unparenthesized `a ? b : c ? d : e` is not supported

最近在一个新的服务器上测试一些老代码的时候得到了类似上面的错误&#xff1a; [Thu Apr 25 07:37:34.139768 2024] [php:error] [pid 691410] [client 192.168.1.229:57183] PHP Fatal error: Unparenthesized a ? b : c ? d : e is not supported. Use either (a ? b : …

DeblurGAN-v2: Deblurring (Orders-of-Magnitude) Faster and Better

文章目录 摘要1、引言2、相关工作2.1、图像去模糊2.2、生成对抗网络 3、DeblurGAN-v2 架构3.1、特征金字塔去模糊3.2、骨干网络的选择&#xff1a;性能与效率之间的权衡3.3、双尺度RaGAN-LS判别器3.4、训练数据集 4、实验评估4.1、实现细节4.2、在GoPro数据集上的定量评估4.3、…

服务器数据恢复—存储硬盘坏道,指示灯亮黄色的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台某品牌EqualLogic PS系列某型号存储&#xff0c;存储中有一组由16块SAS硬盘组建的RAID5磁盘阵列&#xff0c;RAID5上划分VMFS文件系统存放虚拟机文件。存储系统上层一共分了4个卷。 raid5阵列中磁盘出现故障&#xff0c;有2块硬盘…

5款文案生成器,帮你智能写作优秀文案

在当今数字化时代&#xff0c;文案写作是营销和传播领域中至关重要的一环。然而&#xff0c;对于许多人来说&#xff0c;撰写引人注目且有吸引力的文案可能是一项具有挑战性的任务。这就是为什么文案生成器变得如此受欢迎的原因。通过结合人工智能和自然语言处理技术&#xff0…

C++之STL-String

目录 一、STL简介 1.1 什么是STL 1.2 STL的版本 1.3 STL的六大组件 ​编辑 1.4 STL的重要性 二、String类 2.1 Sting类的简介 2.2 string之构造函数 2.3 string类对象的容量操作 2.3.1 size() 2.3.2 length() 2.3.3 capacity() 2.3.4 empty() 2.3.5 clear() 2.3.6…

JDBC查询大数据时怎么防止内存溢出-流式查询

文章目录 1.前言2.流式查询介绍3.使用流式查询3.1不开启流式查询的内存占用情况3.2开启流式查询的内存占用情况 4.开启流式查询的注意点 1.前言 在使用 JDBC 查询大数据时&#xff0c;由于 JDBC 默认将整个结果集加载到内存中&#xff0c;当查询结果集过大时&#xff0c;很容易…

【项目】YOLOv8/YOLOv5/YOLOv9半监督ssod火灾烟雾检测(YOLOv8_ssod)

假期闲来无事找到一份火灾烟雾数据集&#xff0c;自己又补充标注了一些&#xff0c;通过论文检索发现现在的火灾检测工作主要局限于对新场景的泛化性不够强&#xff0c;所以想着用半监督&#xff0c;扩充数据集的方法解决这个问题&#xff0c;所以本文结合使用现在检测精度较高…

Canal入门使用

说明&#xff1a;canal [kə’nl]&#xff0c;译意为水道/管道/沟渠&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费&#xff08;官方介绍&#xff09;。一言以蔽之&#xff0c;Canal是一款实现数据同步的组件。可以实现数据库之间、数…

网络相关知识总结

1、网口设置 网口设置IP&#xff0c;即操作/etc/sysconfig/network-scripts路径下的ifcfg-xx文件 主要参数详解&#xff1a; DEVICE:网口名 ONBOOT&#xff1a;表示启动系统时是否激活网卡&#xff0c;yes为激活&#xff0c;no不激活 HWADDR:mac值 DEFROUTE://默认路由设置…

[C++基础学习]----01-C++数据类型详解

前言 C是一种静态类型的编程语言&#xff0c;它提供了丰富的数据类型来存储和操作数据。这些数据类型为C程序员提供了丰富的选择&#xff0c;可以根据具体需求来选择最合适的类型来存储和操作数据。下面详细解释一些常见的C数据类型&#xff0c;包括其原理和使用方法&#xff1…

ADOP带您科普什么是光纤网卡,它跟普通网卡有什么区别?

光纤网卡&#xff0c;也称为网络适配器或网络接口卡&#xff08;NIC&#xff09;&#xff0c;是一种用于将计算机和服务器等设备连接到数据网络的硬件设备。它通常装有一个或多个端口&#xff0c;可以通过这些端口连接不同类型的网络线缆&#xff0c;如RJ45接口的网络跳线或SFP…

云贝餐饮连锁V2-2.9.9源码

云贝餐饮连锁V2独立版、版本更新至2.9.9&#xff0c;小程序、公众号版本&#xff0c;全插件&#xff0c;公众号小程序端&#xff0c;独立版&#xff1b; 带商家端&#xff0c;修复收银台、排队点餐、堂食点餐&#xff1b;最新版更新 搭建环境教程: 系统环境&#xff1a;CentO…

Wi-Fi HaLow:重塑物联网的未来

Wi-Fi HaLow&#xff1a;引领物联网连接的革命 数字时代的蓬勃发展正在引发一场深刻的变革&#xff0c;物联网已经融入到我们的日常生活和工作中&#xff0c;成为不可或缺的一部分。随着新一代Wi-Fi技术一Wi-Fi HaLow的崭露头角&#xff0c;有望在2024年及未来&#xff0c;重新…

stm32f4单片机强制类型转换为float程序跑飞问题

如题&#xff0c;在一个数据解析函数中使用了*(float *)&data[offset]&#xff0c;其中data为uint8类型指针&#xff0c;指向的value地址为 可以看到地址0x20013A31非对齐&#xff0c;最终在执行VLDR指令时导致跑飞 VLDR需要使用对齐访问 跑飞后查看SCB寄存器发现确实是非…

磁盘未格式化,数据恢复大揭秘

一、磁盘未格式化现象概述 在日常使用电脑的过程中&#xff0c;我们有时会遇到磁盘未格式化的提示&#xff0c;这意味着我们的磁盘突然间变得不可识别&#xff0c;所有的数据和文件都似乎消失了。这种情况常常发生在外接硬盘、U盘等存储设备上&#xff0c;给我们的工作和生活带…