一文带你看懂多线程编程

news2024/11/17 0:49:51

title: 深入理解多线程编程
date: 2024/4/25 17:32:02
updated: 2024/4/25 17:32:02
categories:

  • 后端开发

tags:

  • 线程同步
  • 互斥锁
  • 死锁避免
  • 竞态条件
  • 线程池
  • 异步编程
  • 性能优化

第一章:多线程基础

1.1 线程概念与原理

  • 线程:在操作系统中,一个程序可以被划分为多个执行流,每个执行流就是一个独立的线程。线程是进程中的一个执行实体,它可以拥有自己的局部变量、栈和程序计数器。
  • 并发执行:线程允许程序同时执行多个任务,每个任务在单个处理器核心上交替执行,看起来像是同时进行的。
  • 线程与进程的区别:线程是进程内的一个执行单元,进程是资源分配和独立执行的基本单位。一个进程可以包含多个线程,但一个线程只能属于一个进程。

1.2 多线程编程的优势

  • 提高响应性:多线程允许程序在等待I/O操作时继续执行其他任务,提高用户体验。
  • 资源利用:通过并发,可以更有效地利用处理器的多核心优势,提高系统性能。
  • 任务并行:适合处理大量独立或部分独立的计算任务,如网络请求、文件处理等。

1.3 多线程编程的应用场景

  • Web服务器:处理并发请求,每个请求作为独立的线程处理。
  • 游戏开发:游戏中的多线程用于音频、图形渲染和逻辑处理的分离。
  • 数据分析:大数据处理、机器学习中的并行计算。
  • 用户界面:线程可以用于实现后台任务的异步执行,避免阻塞UI线程。

1.4 线程的创建与销毁

  • 创建线程

    • JavaThread类的Thread构造函数或Runnable接口实现。
    • C++ :std::thread或C11的_beginthread函数。
    • Pythonthreading.Threadconcurrent.futures.ThreadPoolExecutor
  • 线程启动:调用线程的start()方法,线程进入就绪状态。
  • 线程执行:线程执行时,会自动获取CPU时间片。
  • 销毁线程:Java中使用join()方法等待线程结束,然后调用stop()interrupt(),C++中使用join()detach()
  • 线程池:为避免频繁创建和销毁线程,可以使用线程池管理线程,如Java的ExecutorService

第二章:线程同步与互斥

2.1 线程同步与互斥的重要性

  • 线程同步:确保多个线程在共享资源时不会同时修改,防止数据不一致和死锁。例如,共享变量的更新。
  • 互斥:确保同一时间只有一个线程访问特定资源,防止多个线程同时操作可能导致的错误。
  • 重要性:在多线程环境中,没有适当的同步和互斥,可能会导致数据破坏、程序崩溃或性能问题。

2.2 同步机制

1. 信号量(Semaphore)
  • 定义:一种计数资源,可以控制同时访问资源的线程数量。
  • 操作:线程获取信号量(减1),当计数为0时阻塞;线程释放信号量(加1),唤醒等待队列的线程。
  • 应用场景:控制对共享资源的访问,如线程池中的任务队列。
2. 条件变量(Condition Variables)
  • 定义:允许线程在满足特定条件时进入或退出等待状态。
  • 操作wait()进入等待状态,signal()唤醒一个等待线程,broadcast()唤醒所有等待线程。
  • 应用场景:线程间的协作,如生产者-消费者模型。

2.3 互斥机制

1. 互斥量(Mutex)
  • 定义:一种锁,一次只允许一个线程访问共享资源。
  • 操作lock()获取锁,unlock()释放锁。获取锁时,其他线程会阻塞。
  • 应用场景:保护共享数据,防止并发修改。
2. 读写锁(Read-Write Lock)
  • 定义:允许多个读线程同时访问,但只允许一个写线程。
  • 操作readLock()读锁,writeLock()写锁,unlockRead()释放读锁,unlockWrite()释放写锁。
  • 应用场景:读操作比写操作多时,提高并发性能。

第三章:线程安全与数据共享

3.1 线程安全的概念

  • 线程安全:在多线程环境下,数据结构和代码不依赖于任何特定的线程执行顺序,保证在任何情况下都能得到正确的结果。
  • 关键:确保对共享数据的访问不会导致数据不一致或并发问题。

3.2 共享资源的保护和访问控制

  • 保护

    • 静态保护:数据成员声明为volatile,确保读写操作不会被优化掉。
    • 动态保护:使用锁(如互斥量)在访问共享数据时进行控制。
  • 访问控制

    • 封装:将数据封装在类中,通过方法访问,控制对数据的直接访问。
    • 访问修饰符:在C++中,使用privateprotectedpublic来限制不同作用域的访问。

3.3 原子操作和并发数据结构

1. 原子操作(Atomic Operations)
  • 定义:一组操作在单个处理器周期内完成,不会被其他线程中断。
  • 重要性:保证数据更新的完整性,避免竞态条件。
  • 语言支持:C++11引入了std::atomic,Java有synchronized关键字,C#有Interlocked类。
2. 并发数据结构
  • 目的:设计特殊的线程安全的数据结构,如:

    • 无锁数据结构:如无锁栈、无锁队列,通过特定的算法避免锁的使用。
    • 锁优化:如读写锁(如读写锁的std::mutexstd::shared_mutex)。
  • 例子std::atomic_flag(C++)或java.util.concurrent.locks.ReentrantLock(Java)。

第四章:死锁与竞态条件

4.1 死锁和竞态条件的产生原因

  • 死锁:多个线程或进程因争夺资源而陷入僵局,等待其他资源被释放。

    • 产生原因:互斥访问、持有并等待、不可抢占、循环等待。
  • 竞态条件:多个线程同时访问共享资源,最终导致结果取决于线程执行的顺序。

    • 产生原因:未正确同步共享资源的访问、对共享资源的非原子操作。

4.2 避免死锁和竞态条件的方法

1. 避免死锁的方法
  • 破坏死锁产生的条件:破坏互斥、持有并等待、不可抢占、循环等待中的一个或多个条件。
  • 资源分配策略:按序申请资源,避免环路等待。
2. 避免竞态条件的方法
  • 同步机制:使用锁、信号量等同步机制确保对共享资源的互斥访问。
  • 原子操作:确保对共享资源的操作是原子的,避免数据不一致。

4.3 死锁检测和解决技术

  • 死锁检测

    • 资源分配图:通过资源分配图检测是否存在环路,从而判断是否存在死锁。
    • 超时机制:设置超时时间,超时则释放资源并重试。
  • 死锁解决

    • 资源预分配:提前分配资源,避免在运行时请求资源。
    • 资源剥夺:当检测到死锁时,抢占资源以解除死锁。
    • 撤销和回滚:撤销一些操作,回滚到之前的状态。

第五章:高级线程编程技术

5.1 线程池的设计和实现

  • 线程池:一种管理和复用线程的机制,通过预先创建一组线程,可以有效地管理并发任务的执行。
  • 设计要点

    • 线程池大小:控制线程数量,避免资源浪费。
    • 任务队列:存储待执行的任务,实现任务的排队和调度。
    • 线程池管理:包括线程的创建、销毁、任务分配等操作。
  • 实现方法

    • Java中的线程池:使用Executor框架及其实现类如ThreadPoolExecutor
    • C++中的线程池:手动创建线程池,维护线程、任务队列等。

5.2 异步编程和事件驱动模型

  • 异步编程:通过异步操作,可以在任务进行的同时继续执行其他操作,提高系统的并发性能。
  • 事件驱动模型:基于事件和回调机制,当事件发生时触发回调函数,实现非阻塞的事件处理。
  • 实现方法

    • 异步编程:使用FuturePromise等机制实现异步操作。
    • 事件驱动模型:使用事件循环、回调函数等实现事件的监听和处理。

5.3 基于消息队列的线程通信

  • 消息队列:一种进程间或线程间通信的方式,通过队列存储消息实现异步通信。
  • 线程通信:多线程间通过消息队列进行通信,实现解耦和并发处理。
  • 实现方法

    • 生产者-消费者模型:一个线程生产消息放入队列,另一个线程消费消息进行处理。
    • 消息队列库:如RabbitMQKafka等可以用于实现消息队列通信。

第六章:性能优化与调试技巧

6.1 多线程程序的性能优化策略

  • 并发性能瓶颈:多线程程序中常见的性能瓶颈包括锁竞争、线程间通信开销等。
  • 优化策略

    • 减少锁竞争:尽量缩小锁的粒度,使用无锁数据结构或使用读写锁等减少竞争。
    • 提高并行度:增加任务的并行度,减少线程间的依赖关系,提高系统的并发性能。
    • 优化数据访问:减少内存访问次数,提高缓存命中率,优化数据结构和算法以提高性能。
    • 使用线程池:合理使用线程池,控制线程的数量,避免线程创建和销毁的开销。

6.2 线程调度和优先级设置

  • 线程调度:操作系统根据线程的优先级和调度算法来决定哪个线程获得CPU的执行权。
  • 优先级设置:可以通过设置线程的优先级来影响线程的调度顺序,但应谨慎使用,避免陷入优先级反转等问题。

6.3 多线程程序的调试方法和工具

  • 调试方法

    • 打印日志:在关键代码段打印日志以观察程序执行情况。
    • 断点调试:使用调试器设置断点,逐步调试程序以发现问题。
    • 内存检测工具:使用内存检测工具检测内存泄漏和越界访问等问题。
    • 性能分析工具:使用性能分析工具分析程序的性能瓶颈,如CPU占用、内存使用情况等。
  • 常用工具

    • GDB:Linux系统下的调试器,支持命令行和图形界面调试。
    • Valgrind:用于检测内存错误的工具,可以检测内存泄漏、越界访问等问题。
    • perf:Linux系统下的性能分析工具,可以用于分析程序的CPU使用情况、函数调用关系等。

附录:多线程编程实践

实际案例分析和解决方案

案例一:线程安全问题

问题:多个线程同时修改一个共享的数据结构,导致数据不一致。

解决方案

  1. 使用synchronized关键字或ReentrantLock等同步机制,确保同一时间只有一个线程能修改数据。
  2. 使用Atomic类(如AtomicIntegerAtomicLong)进行原子操作,避免数据竞争。

案例二:死锁

问题:两个或更多线程相互等待对方释放资源,导致程序无法继续执行。

解决方案

  1. 避免嵌套锁:尽量分解任务,减少锁的嵌套。
  2. 使用tryLocktryAcquire等方法,设置合理的超时或非阻塞模式。
  3. 使用java.util.concurrent.locks包中的ReentrantLock,提供tryLockunlock方法,确保锁的释放顺序。

案例三:资源竞争与优先级反转

问题:高优先级线程被低优先级线程阻塞,导致低优先级线程长时间占用CPU资源。

解决方案

  1. 使用Thread.Priority设置线程优先级,但要小心优先级反转。
  2. 使用java.util.concurrent.PriorityBlockingQueue等优先级队列。

案例四:线程池滥用

问题:线程池创建过多或线程空闲时间过长,造成资源浪费。

解决方案

  1. 根据任务负载动态调整线程池大小(ThreadPoolExecutorsetCorePoolSizesetMaximumPoolSize)。
  2. 使用FutureExecutorServicesubmit方法,避免阻塞主线程。
  3. 使用ThreadPoolExecutorkeepAliveTime属性配置空闲线程的存活时间。

案例五:线程间的通信

问题:线程需要在执行过程中交换数据或通知其他线程。

解决方案

  1. 使用java.util.concurrent包中的SemaphoreCountDownLatchCyclicBarrierCompletableFuture进行线程通信。
  2. 使用BlockingQueue进行生产者消费者模型。

实战案例

案例一:生产者消费者模型

问题:生产者线程生产数据,消费者线程消费数据,需要有效地协调两者之间的工作。

解决方案

  1. 使用Python中的queue.Queue实现线程安全的队列,生产者往队列中放入数据,消费者从队列中取出数据。
  2. 在Java中可以使用java.util.concurrent.BlockingQueue来实现相同的功能。

案例二:多线程并发爬虫

问题:多个线程同时爬取网页数据,需要避免重复爬取和有效管理爬取任务。

解决方案

  1. 使用Python的concurrent.futures.ThreadPoolExecutor创建线程池,管理爬虫任务。
  2. 在Java中可以使用ExecutorServiceCallable接口实现类似的功能。

案例三:多线程文件下载器

问题:多个线程同时下载大文件,需要合理分配任务和监控下载进度。

解决方案

  1. 在Python中可以使用threading.Threadrequests库实现多线程文件下载器。
  2. 在Java中可以使用java.util.concurrent.ExecutorServicejava.net.URL进行多线程文件下载。

案例四:多线程数据处理

问题:需要同时处理大量数据,提高数据处理效率。

解决方案

  1. 使用Python的concurrent.futures.ProcessPoolExecutor创建进程池,实现多进程数据处理。
  2. 在Java中可以使用java.util.concurrent.ForkJoinPool进行类似的多线程数据处理。

案例五:多线程图像处理

问题:需要对大量图像进行处理,加快处理速度。

解决方案

  1. 使用Python的concurrent.futures.ThreadPoolExecutor创建线程池,实现多线程图像处理。
  2. 在Java中可以使用java.util.concurrent.ExecutorServicejava.awt.image.BufferedImage进行多线程图像处理。

案例六:多线程日志处理

问题:需要同时记录大量日志,避免日志丢失或混乱。

解决方案

  1. 使用Python的logging模块结合多线程技术,实现线程安全的日志处理。
  2. 在Java中可以使用java.util.logging.Logger和适当的同步机制实现多线程日志处理。

案例七:多线程任务调度

问题:需要按照一定的调度规则执行多个任务,确保任务按时完成。

解决方案

  1. 使用Python的schedule模块和多线程技术,实现多线程任务调度。
  2. 在Java中可以使用java.util.concurrent.ScheduledExecutorService实现类似的任务调度功能。

案例八:多线程网络编程

问题:需要同时处理多个网络连接,提高网络通信效率。

解决方案

  1. 使用Python的socket模块结合多线程技术,实现多线程网络编程。
  2. 在Java中可以使用java.net.Socketjava.util.concurrent.ExecutorService实现多线程网络编程。

案例九:多线程GUI应用

问题:需要在GUI应用中实现多线程任务,确保UI界面响应性。

解决方案

  1. 在Python中可以使用tkinterPyQt等GUI库结合多线程技术实现多线程GUI应用。
  2. 在Java中可以使用SwingJavaFX结合SwingWorkerPlatform.runLater实现类似功能。

案例十:多线程数据库操作

问题:需要同时进行大量数据库操作,提高数据库访问效率。

解决方案

  1. 使用Python的threading.Thread结合数据库连接池实现多线程数据库操作。
  2. 在Java中可以使用java.sql.Connectionjava.util.concurrent.ExecutorService实现多线程数据库操作。

常见多线程编程问题的解决方法

常见多线程编程问题的解决方法包括但不限于以下几个方面:

  1. 竞态条件(Race Condition) :

    • 使用互斥锁(Mutex)或信号量(Semaphore)来保护共享资源,确保在同一时间只有一个线程可以访问共享资源。
    • 使用条件变量(Condition Variable)来实现线程间的同步,避免出现数据竞争的情况。
    • 使用原子操作(Atomic Operations)来确保对共享变量的操作是原子性的。
  2. 死锁(Deadlock) :

    • 避免线程之间循环等待资源,尽量按照固定的顺序获取资源。
    • 使用超时机制或者避免在持有资源的情况下尝试获取其他资源,以避免死锁的发生。
    • 使用资源分配图(Resource Allocation Graph)等工具来分析和避免潜在的死锁情况。
  3. 饥饿(Starvation) :

    • 使用公平的调度算法来确保所有线程都有机会获取资源,避免某些线程长时间无法执行的情况。
    • 使用优先级调度算法来合理分配CPU时间,避免某些线程长时间被其他线程抢占资源。
  4. 线程安全(Thread Safety) :

    • 使用互斥锁、条件变量等同步机制来保护共享数据,确保多个线程可以安全地访问和修改共享数据。
    • 避免线程之间的数据争用,尽量将数据的访问限制在一个线程内部,减少共享数据的使用。
  5. 性能问题

    • 使用线程池(ThreadPool)来管理线程的创建和销毁,避免频繁创建线程的开销。
    • 使用合适的线程数量来充分利用多核处理器的性能,避免线程数量过多导致上下文切换开销增大。
  6. 线程间通信

    • 使用消息队列、管道、共享内存等机制来实现线程间的通信,确保线程之间可以安全地传递数据和消息。
    • 使用信号量、条件变量等同步机制来协调线程的执行顺序,确保线程按照预期的顺序执行。
  7. 资源管理

    • 合理管理线程的资源占用,避免内存泄漏和资源浪费的情况。
    • 使用RAII(资源获取即初始化)等技术来确保资源在使用完毕后能够正确释放。

多线程编程的最佳实践和技巧

多线程编程的最佳实践和技巧主要包括以下几个方面:

  1. 明确任务划分

    • 将任务拆分成独立且可重用的线程或任务,每个任务尽量独立,减少线程间的耦合性。
    • 使用线程池,避免频繁创建和销毁线程,提高性能。
  2. 使用锁和同步机制

    • 为共享资源使用互斥锁(Mutex)或信号量(Semaphore),确保在任何时候只有一个线程可以访问。
    • 避免过度使用锁,可能导致性能下降和死锁,尽量减少锁的粒度和持有时间。
    • 使用条件变量(Condition Variable)来实现线程间的协作,提高同步的灵活性。
  3. 避免死锁

    • 按照固定的顺序获取资源,或者使用资源所有权(Resource Ownership)模型。
    • 设置超时机制,防止线程无限等待。
    • 使用死锁检测工具或算法提前预防死锁。
  4. 线程优先级

    • 根据任务的优先级和系统的调度策略,合理设置线程的优先级。
    • 避免优先级反转,即高优先级线程被低优先级线程阻塞的情况。
  5. 线程通信

    • 使用消息队列、管道或共享内存等机制进行线程间通信,保持数据的一致性。
    • 使用线程安全的数据结构,如无锁数据结构或原子操作。
  6. 资源管理

    • 使用智能指针(如C++的std::unique_ptrstd::shared_ptr)来自动管理线程本地资源。
    • 为线程设置适当的生命周期,避免资源泄露。
  7. 测试和调试

    • 使用并发测试工具来检测多线程程序的正确性。
    • 使用日志和调试工具,如std::thread::hardware_concurrency()来跟踪线程执行情况。
    • 尽量使用单元测试和压力测试,确保程序在各种并发场景下都能正确工作。
  8. 线程池和异步编程

    • 使用线程池来复用线程,减少线程创建和销毁的开销。
    • 使用异步编程模式(如回调、Future/Promise、async/await)来处理耗时操作,提高程序响应速度。
  9. 性能优化

    • 通过限制线程数量来平衡CPU开销和线程切换成本。
    • 优化锁的粒度和持有时间,减少上下文切换。
    • 使用CPU affinity(如果支持)来指定线程运行在特定核心上。

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

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

相关文章

探索SSH:常见功能与使用技巧

文章目录 远程登录密钥认证文件传输端口转发执行远程命令会话保持总结 SSH(Secure Shell)是一种安全网络协议,用于通过加密的方式在网络上安全地进行远程登录和执行命令。它是管理远程服务器和网络设备的重要工具之一。在本文中,我…

【TDengine】mac m1解决no taos in java.library.path

前言 使用macos搭建springbootmybatisplus,通过mqtt将数据更新到tdenigne 3.2.3,数据源使用远程服务器的tdengine。 问题 启动时报错: Caused by: java.lang.UnsatisfiedLinkError: no taos in java.library.path 以下是官方文档 打开本…

【电路笔记】-Colpitts振荡器

Colpitts振荡器 文章目录 Colpitts振荡器1、概述2、基本Colpitts 振荡器电路3、示例14、使用运算放大器的Colpitts振荡器5、总结Colpitts 振荡器设计使用两个中心抽头电容器与并联电感器串联,形成产生正弦振荡的谐振储能电路。 1、概述 在许多方面,Colpitts 振荡器与我们在上…

(开源版)企业AI名片S2B2C商城系统商业计划书

团队使命 擎动人工智能跃迁,融技术与商业之行 项目背景 话说2022年12月7日那天,国务院大大发布了个重磅消息,宣布咱们国家的三年抗疫大战终于告一段落,全面放开啦!这意味着咱们的市场经济要重新焕发生机啦&#xff…

LeetCode //C - 38. Count and Say Medium Topics Companies

38. Count and Say The count-and-say sequence is a sequence of digit strings defined by the recursive formula: countAndSay(1) “1”countAndSay(n) is the way you would “say” the digit string from countAndSay(n-1), which is then converted into a differen…

【C语言】万字详讲操作符

目录 前言 一、操作符分类 二、算数操作符 三、移位操作符 四、位操作符 五、赋值操作符 六、单目操作符 6.1 逻辑反操作 6.2 负值与正值 6.3 取地址 6.4 sizeof 6.5 取反操作符 6.6 --和操作符 6.7 间接访问操作符(解引用操作符) 6.8 强…

比较好的平民衣服品牌有哪些?平价质量好短袖品牌推荐

随着气候变暖,夏天的持续时间似乎越来越长,短袖作为夏季的必备服装,受到了广大男士的青睐。然而,面对市场上众多的短袖品牌和不同的质量,大家都觉得选短袖的时候实在难以找到质量好且合适自己的。 选择合适的短袖确实…

中级信息系统管理工程师-必会题锦集

文章目录 中级信息系统管理工程师-必会题锦集题目一CPU[解析]试题二 CPU[解析] 中级信息系统管理工程师-必会题锦集 题目一CPU CPU中(1)不仅要保证指令的正确执行,还要能够处理异常事件。 A. 运算器 B. 控制器 C. 寄存器组 D. 内部总线 [解…

Elasticsearch单机部署(Linux)

1. 准备环境 本文中Elasticsearch版本为7.12.0,JDK版本为1.8.0,Linux环境部署。 扩展: (1)查看Elasticsearch对应的常用的jdk版本如下:(详情可看官网的支持一览表) Elasticsearch a…

牛客NC221 集合的所有子集(二)【中等 深度优先,子集,排列组合 C++/Java/Go/PHP】

题目 题目链接: https://www.nowcoder.com/practice/a3dfd4bc8ae74fad9bc65d5ced7ae813 核心 和n数之和的问题 差不多,都是需要找到数字的排列组合参考答案C class Solution {public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改&a…

获取boss直聘城市地区josn数据

获取boss直聘城市地区josn数据 当我需要爬取多个城市的地区的时候,只能手动点击,然后一个一个看 结果: 能看到所有区域所有子地区的地区代码 解析该JSON数据 import pandas as pd import requests code[] area[] 城市代码101210100 res…

ScriptableObject数据容器讲解

概述 是Unity提供的一个用于创建可重用的数据容器或逻辑的基类。 ScriptableObject 是继承自 UnityEngine.Object 的一个类,但与普通的 MonoBehaviour 不同,它不能附加到GameObject上作为组件。 相反,ScriptableObject 通常用于存储和管理…

飞鹤与满趣健达成战略合作 加速深化国际化布局

继获得加拿大地区首张婴幼儿配方奶粉生产执照后,中国飞鹤的海外征途再添新动作。4月25日,中国飞鹤加拿大皇家妙克与美国婴童用品巨头满趣健(Munchkin)在北京正式达成战略合作。此次合作彰显了中国乳企的硬核实力,也是飞…

java:Http协议和Tomcat

HTTP协议 Hyper Text Transfer Protocol 超文本传输协议,规定了浏览器和服务器之间数据传输的规则 特点: 基于TCP协议,面向连接,安全 基于请求响应模型:一次请求对应一次响应 HTTP协议是无状态协议,对事务的处理没有记忆能力,每次请求-响应都是独立的. 优点 速度较快 …

Win11和WinRAR取消折叠菜单恢复经典菜单

这里写目录标题 前言1. Win11恢复经典右键菜单1.1 修改前1.2 恢复成经典右键菜单1.3 修改后1.4 想恢复怎么办? 2. WinRAR取消折叠菜单恢复经典菜单2.1 修改前2.2 修改恢复为经典菜单2.3 修改后2.4 想恢复怎么办? 前言 最近换回了Windows电脑&#xff0c…

网络攻击近在咫尺:数据加密与SSL成为信息安全之盾

随着互联网的日益普及和科技的迅猛发展,网络攻击已经成为信息安全领域面临的一大难题。近期,一场网络安全实验让我们对网络攻击有了更为深刻的认识。在实验中,网络安全工程师通过模拟攻击,展示了木马植入、文件浏览、键盘监听、病…

618大促有哪些值得买的家居好物?618五款必Buy好物

来了!来了!万众瞩目的618购物狂欢节即将拉开帷幕,我们的目标清晰而坚定,那就是用最实惠的价格尽情享受购物的乐趣。然而,面对各种纷繁复杂的促销活动和琳琅满目的商品,选择困难症似乎也在悄然滋生。因此&am…

安全AI未来 | C3安全大会 · 2024,数据驱动 AI原生

数字为时代变革注入动力,AI为重塑社会文明带来原力。数智浪潮中,我们见证着时代跃迁的巨变,面临着适变、应变、驭变的挑战。 数字驱动、AI原生。数字的流动不仅承载着信息,更将激活未来的无限价值;AI,不…

FastAPI从入门到实战(16)——请求参数汇总

FastAPI有各种各样的参数,包括: url参数(定义在url中的参数)param参数(使用url后面?xxxx)定义的参数body参数(在请求主体中携带的json参数)form参数(在请求主体中携带的web表单参数)cookie参数(在请求的cookie中携带的参数)file参数(客户端上传的文件) 1. url参数 from fas…

金属冶炼及压延加工制造数字孪生可视化平台,推进行业数字化转型

金属冶炼及压延加工制造数字孪生可视化平台,推进行业数字化转型。随着科技的不断进步和工业的快速发展,金属冶炼及压延加工行业正面临着前所未有的挑战和机遇,数字化转型成为了行业发展的必然趋势。在这个过程中,数字孪生可视化平…