当前位置: 首页 > news >正文

python 进程、线程、协程基本使用

    • 1、进程、线程以及协程
      • 【1】进程概念
      • 【2】线程的概念
        • 线程的生命周期
        • 进程与线程的区别
      • 【3】协程(Coroutines)
    • 2、多线程实现
      • 【1】threading模块
      • 【2】互斥锁
      • 【3】线程池
      • 【4】线程应用
    • 3、多进程实现
    • 4、协程实现
      • 【1】yield与协程
      • 【2】asyncio模块
      • 【3】3.8版本+
      • 【4】aiohttp

1. 并发与并行
2. IO密集型任务和计算密集型任务
3. 同步与异步
4. IO模型(IO多路复用)
5. 内核态多线程,用户态多线程

所谓并发编程是指在一台处理器上“同时”处理多个任务。并发是在同一实体上的多个事件**。强调多个事件在同一时间间隔发生。**

1、进程、线程以及协程

【1】进程概念

我们都知道计算机的核心是CPU,它承担了所有的计算任务;而操作系统是计算机的管理者,它负责任务的调度、资源的分配和管理,统领整个计算机硬件;应用程序则是具有某种功能的程序,程序是运行于操作系统之上的。

进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。

多道技术:空间复用+时间复用,于是有了进程!

进程是一种抽象的概念,从来没有统一的标准定义。进程一般由程序、数据集合和进程控制块三部分组成。

例子:我和我的女朋友们的故事我就是CPU,我跟三个女朋友玩就是三个任务1. 我教第一个女朋友做菜,菜谱就是程序,食材就是数据,我做饭的过程就是一个进程(切换,状态保存)2. 我给第二个女朋友治疗脚伤,医疗手册就是程序,医药箱就是数据,治疗脚伤的过程就是第二个进程。。。

进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型中,进程状态分为三个基本状态,即运行态,就绪态,阻塞态。在五态模型中,进程分为新建态、终止态,运行态,就绪态,阻塞态。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

【2】线程的概念

在早期的操作系统中并没有线程的概念,进程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。任务调度采用的是时间片轮转的抢占式调度方式,而进程是任务调度的最小单位,每个进程有各自独立的一块内存,使得各个进程之间内存地址相互隔离。后来,随着计算机的发展,对CPU的要求越来越高,进程之间的切换开销较大,已经无法满足越来越复杂的程序的要求了。于是就发明了线程。

线程是程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。

一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。

线程的生命周期

当线程的数量小于处理器的数量时,线程的并发是真正的并发,不同的线程运行在不同的处理器上。但当线程的数量大于处理器的数量时,线程的并发会受到一些阻碍,此时并不是真正的并发,因为此时至少有一个处理器会运行多个线程。

在单个处理器运行多个线程时,并发是一种模拟出来的状态。操作系统采用时间片轮转的方式轮流执行每一个线程。现在,几乎所有的现代操作系统采用的都是时间片轮转的抢占式调度方式,如我们熟悉的Unix、Linux、Windows及macOS等流行的操作系统。

我们知道线程是程序执行的最小单位,也是任务执行的最小单位。在早期只有进程的操作系统中,进程有五种状态,创建、就绪、运行、阻塞(等待)、退出。早期的进程相当于现在的只有单个线程的进程,那么现在的多线程也有五种状态,现在的多线程的生命周期与早期进程的生命周期类似。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

线程的生命周期# 创建:一个新的线程被创建,等待该线程被调用执行;
# 就绪:时间片已用完,此线程被强制暂停,等待下一个属于它的时间片到来;
# 运行:此线程正在执行,正在占用时间片;
# 阻塞:也叫等待状态,等待某一事件(如IO或另一个线程)执行完;
# 退出:一个线程完成任务或者其他终止条件发生,该线程终止进入退出状态,退出状态释放该线程所分配的资源。
进程与线程的区别

前面讲了进程与线程,但可能你还觉得迷糊,感觉他们很类似。的确,进程与线程有着千丝万缕的关系,下面就让我们一起来理一理:

  1. 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;
  2. 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线;
  3. 进程之间相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)及一些进程级的资源(如打开文件和信号),某进程内的线程在其它进程不可见;
  4. 调度和切换:线程上下文切换比进程上下文切换要快得多。

【3】协程(Coroutines)

协程(Co-routine),也可称为微线程,或非抢占式的多任务子例程,一种用户态的上下文切换技术(通过一个线程实现代码块间的相互切换执行)。这种由程序员自己写程序来管理的轻量级线程叫做『用户空间线程』,具有对内核来说不可见的特性。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。

协程解决的是线程的切换和内存开销的问题

* 用户空间 首先是在用户空间, 避免内核态和用户态的切换导致的成本。
* 由语言或者框架层调度
* 更小的栈空间允许创建大量实例(百万级别)

2、多线程实现

【1】threading模块

Python提供两个模块进行多线程的操作,分别是threadthreading,前者是比较低级的模块,用于更底层的操作,一般应用级别的开发不常用。

import timedef foo():print("foo start...")time.sleep(5)print("foo end...")def bar():print("bar start...")time.sleep(3)print("bar end...")# 串行版本
# start = time.time()
# foo()
# bar()
# end = time.time()
# print("cost timer:", end - start)# 多线程并发版本import threadingstart = time.time()
t1 = threading.Thread(target=foo, args=())
t1.start()
t2 = threading.Thread(target=bar, args=())
t2.start()# 等待所有子线程结束
# t1.join()  # 等待子线程t1
# t2.join()  # 等待子线程t2
end = time.time()
print(end - start)

【2】互斥锁

import time
import threadingLock = threading.Lock()def addNum():global num  # 在每个线程中都获取这个全局变量# 上锁Lock.acquire()t = num - 1time.sleep(0.0001)num = tLock.release()# 放锁num = 100  # 设定一个共享变量thread_list = []for i in range(100):t = threading.Thread(target=addNum)t.start()thread_list.append(t)for t in thread_list:  # 等待所有线程执行完毕t.join()print('Result: ', num)

【3】线程池

系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互。在这种情形下,使用线程池可以很好地提升性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池。

线程池在系统启动时即创建大量空闲的线程,程序只要将一个函数提交给线程池,线程池就会启动一个空闲的线程来执行它。当该函数执行结束后,该线程并不会死亡,而是再次返回到线程池中变成空闲状态,等待执行下一个函数。

此外,使用线程池可以有效地控制系统中并发线程的数量。当系统中包含有大量的并发线程时,会导致系统性能急剧下降,甚至导致解释器崩溃,而线程池的最大线程数参数可以控制系统中并发线程的数量不超过此数。

import time
from concurrent.futures import ThreadPoolExecutordef task(i):print(f'任务{i}开始!')time.sleep(i)print(f'任务{i}结束!')return istart = time.time()
pool = ThreadPoolExecutor(3)future01 = pool.submit(task, 1)
# print("future01是否结束", future01.done())
# 当程序使用 Future 的 result() 方法来获取结果时,该方法会阻塞当前线程,如果没有指定 timeout 参数,当前线程将一直处于阻塞状态,直到 Future 代表的任务返回。
# print("future01的结果", future01.result())  # 同步等待
future02 = pool.submit(task, 2)
future03 = pool.submit(task, 3)
pool.shutdown()  # 阻塞等待
print(f"程序耗时{time.time() - start}秒钟")print("future01的结果", future01.result())
print("future02的结果", future02.result())
print("future03的结果", future03.result())

使用线程池来执行线程任务的步骤如下:

  1. 调用 ThreadPoolExecutor 类的构造器创建一个线程池。
  2. 定义一个普通函数作为线程任务。
  3. 调用 ThreadPoolExecutor 对象的 submit() 方法来提交线程任务。
  4. 当不想提交任何任务时,调用 ThreadPoolExecutor 对象的 shutdown() 方法来关闭线程池。

【4】线程应用

import requests
from lxml import etree
import os
import asyncio
import time
import threadingdef get_img_urls():res = requests.get("https://www.pkdoutu.com/photo/list/", headers={"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"})selector = etree.HTML(res.text)img_urls = selector.xpath('//li[@class="list-group-item"]/div/div/a/img[@data-backup]/@data-backup')print(img_urls)return img_urlsdef save_img(url):res = requests.get(url)name = os.path.basename(url)with open("imgs/" + name, "wb") as f:f.write(res.content)print(f"{name}下载完成!")def main():img_urls = get_img_urls()# 串行[save_img(url) for url in img_urls]# 协程并发t_list = []for url in img_urls:t = threading.Thread(target=save_img, args=(url,))t.start()t_list.append(t)for t in t_list:t.join()if __name__ == '__main__':start = time.time()main()end = time.time()print(end - start)

针对IO密集型任务,Python多线程可以发挥出不错的并发作用

3、多进程实现

由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。

multiprocessing包是Python中的多进程管理包。与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。该进程可以运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。

python的进程调用:

import multiprocessing
import timedef foo():print("foo start...")time.sleep(5)print("foo end...")def bar():print("bar start...")time.sleep(3)print("bar end...")if __name__ == '__main__':start = time.time()t1 = multiprocessing.Process(target=foo, args=())t1.start()t2 = multiprocessing.Process(target=bar, args=())t2.start()# 等待所有子线程结束t1.join()  # 等待子线程t1t2.join()  # 等待子线程t2end = time.time()print(end - start)

4、协程实现

协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程。

协程拥有自己的寄存器上下文和栈。协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈。因此:

协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换种说法:进入上一次离开时所处逻辑流的位置。

【1】yield与协程


def foo():print("OK1")yield 100  # 切换: 保存/恢复的功能print("OK2")yield 1000def bar():print("OK3")yield 200print("OK4")yield 2000gen = foo()
ret = next(gen)    # gen.__next__()
print(ret)gen2 = bar()
ret2 = next(gen2)  # gen.__next__()
print(ret2)ret = next(gen)    # gen.__next__()
print(ret)ret2 = next(gen2)  # gen.__next__()
print(ret2)

【2】asyncio模块

asyncio即Asynchronous I/O是python一个用来处理并发(concurrent)事件的包,是很多python异步架构的基础,多用于处理高并发网络请求方面的问题。

为了简化并更好地标识异步IO,从Python 3.5开始引入了新的语法async和await,可以让coroutine的代码更简洁易读。

asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任务队列等等。

asyncio 往往是构建 IO 密集型和高层级 结构化 网络代码的最佳选择。

import asyncioasync def task(i):print(f"task {i} start")await asyncio.sleep(1)print(f"task {i} end")# 创建事件循环对象
loop = asyncio.get_event_loop()
# 直接将协程对象加入时间循环中
tasks = [task(1), task(2)]
# asyncio.wait:将协程任务进行收集,功能类似后面的asyncio.gather
# run_until_complete阻塞调用,直到协程全部运行结束才返回
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

task: 任务,对协程对象的进一步封装,包含任务的各个状态;asyncio.Task是Future的一个子类,用于实现协作式多任务的库,且Task对象不能用户手动实例化,通过下面2个函数loop.create_task() 或 asyncio.ensure_future()创建。

import asyncio, timeasync def work(i, n):  # 使用async关键字定义异步函数print('任务{}等待: {}秒'.format(i, n))await asyncio.sleep(n)  # 休眠一段时间print('任务{}在{}秒后返回结束运行'.format(i, n))return i + nstart_time = time.time()  # 开始时间tasks = [asyncio.ensure_future(work(1, 1)),asyncio.ensure_future(work(2, 2)),asyncio.ensure_future(work(3, 3))]loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
loop.close()print('运行时间: ', time.time() - start_time)
for task in tasks:print('任务执行结果: ', task.result())

【3】3.8版本+

async.run() 运行协程
async.create_task()创建task
async.gather()获取返回值


import asyncio, timeasync def work(i, n):  # 使用async关键字定义异步函数print('任务{}等待: {}秒'.format(i, n))await asyncio.sleep(n)  # 休眠一段时间print('任务{}在{}秒后返回结束运行'.format(i, n))return i + ntasks = []
async def main():global taskstasks = [asyncio.create_task(work(1, 1)),asyncio.create_task(work(2, 2)),asyncio.create_task(work(3, 3))]await asyncio.wait(tasks) # 阻塞start_time = time.time()  # 开始时间
asyncio.run(main())
print('运行时间: ', time.time() - start_time)
for task in tasks:print('任务执行结果: ', task.result())

asyncio.create_task() 函数在 Python 3.7 中被加入。

asyncio.gather方法

# 用gather()收集返回值import asyncio, timeasync def work(i, n):  # 使用async关键字定义异步函数print('任务{}等待: {}秒'.format(i, n))await asyncio.sleep(n)  # 休眠一段时间print('任务{}在{}秒后返回结束运行'.format(i, n))return i + nasync def main():tasks = [asyncio.create_task(work(1, 1)),asyncio.create_task(work(2, 2)),asyncio.create_task(work(3, 3))]# 将task作为参数传入gather,等异步任务都结束后返回结果列表response = await asyncio.gather(tasks[0], tasks[1], tasks[2])print("异步任务结果:", response)start_time = time.time()  # 开始时间asyncio.run(main())print('运行时间: ', time.time() - start_time)

【4】aiohttp

我们之前学习过爬虫最重要的模块requests,但它是阻塞式的发起请求,每次请求发起后需阻塞等待其返回响应,不能做其他的事情。本文要介绍的aiohttp可以理解成是和requests对应Python异步网络请求库,它是基于 asyncio 的异步模块,可用于实现异步爬虫,有点就是更快于 requests 的同步爬虫。安装方式,pip install aiohttp。

aiohttp是一个为Python提供异步HTTP 客户端/服务端编程,基于asyncio的异步库。asyncio可以实现单线程并发IO操作,其实现了TCP、UDP、SSL等协议,aiohttp就是基于asyncio实现的http框架。

import aiohttp
import asyncioasync def main():async with aiohttp.ClientSession() as session:async with session.get("http://httpbin.org/headers") as response:print(await response.text())asyncio.run(main())

相关文章:

python 进程、线程、协程基本使用

1、进程、线程以及协程【1】进程概念【2】线程的概念线程的生命周期进程与线程的区别 【3】协程(Coroutines) 2、多线程实现【1】threading模块【2】互斥锁【3】线程池【4】线程应用 3、多进程实现4、协程实现【1】yield与协程【2】asyncio模块【3】3.8版本【4】aiohttp 1. 并发…...

SQLite3进行数据库各项常用操作

目录 前言1、SQLite介绍2、通过SQLite创建一个数据库文件3、往数据库文件中插入数据4、数据库文件信息查询5、修改数据库中的内容6、删除数据库中的内容 前言 本文是通过轻量化数据库管理工具SQLite进行的基础操作和一些功能实现。 1、SQLite介绍 SQLite是一个广泛使用的嵌入…...

Debian GNU/Linux 安装docker与docker compose

安装 Docker 更新包列表 sudo apt update 安装必要的软件包,以便让 APT 可以通过 HTTPS 使用存储库: sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common 添加 Docker 的官方 GPG 密钥: cu…...

图片标注编辑平台搭建系列教程(2)——fabric.js简介

文章目录 综述数据管理图形渲染图形编辑事件监听预告 综述 fabric提供了二维图形编辑需要的所有基础能力,包括:数据管理、图形渲染、图形编辑和事件监听。其中,图形编辑可以通过事件监听和图形渲染来实现,所以可以弃用。数据管理…...

Debian linux版本下运行的openmediavault网盘 千兆网卡升级万兆

一、适用场景 1、使用vmware ESXi虚拟化平台运行多种不同应用服务器时,其中网盘服务器采用开源的openmediavault搭建; 2、将老专业服务器升级千兆网为万兆网; 3、需要转移的数据量大的企业或用户; 4、从服务器到服务器的数据转移…...

前端 CSS 经典:grid 栅格布局

前言:Grid 布局是将容器划分成"行"和"列",产生单元格,然后将"项目"分配给划分好的单元格,因为有行和列,可以看作是二维布局。 一 术语 1. 容器 采用网格布局的区域,也就是…...

多输入多输出通道

文章目录 图像卷积填充和步幅填充步幅 多输入多输出通道1x1卷积层 图像卷积 卷积原理: 就是将之前的大的图片,定义一个核函数,然后经过移动并运算将图片变小了.也就是将图像压缩提取整合特征值. 这里利用的时乘法. 填充和步幅 填充 在应用多层卷积时,我们常常…...

http响应练习—在服务器端渲染html(SSR)

一、什么是服务器端渲染(SSR) 简单说,就是在服务器上把网页生成好,整个的HTML页面生成出来,生成出的页面已经包含了所有必要的数据和结构信息,然后直接发给浏览器进行展现。 二、例题 要求搭建http服务&a…...

C++(8): std::deque的使用

1. std::deque std::deque 是 C 标准库中的一个双端队列容器。这个容器支持在序列的两端进行快速的插入和删除操作,其时间复杂度为常数时间 O(1)。同时,std::deque 也提供了对序列中任意元素的随机访问。 2. 特点 (1)双端操作&…...

openwrt开发包含路由器基本功能的web问题记录

1.这里的扫描怎么实现的先找一些luci代码,在openwrt21版本后,luci用js替换了lua写后台,先找一些代码路径 在openrwt15这部分代码是在这个目录下 feeds/luci/modules/luci-mod-admin-full/luasrc/view/admin_network/wifi_join.htm 里面包含…...

HarmonyOS ArkTS 骨架屏加载显示(二十五)

目录 前言1、骨架屏代码显示2、代码中引用3、效果图展示 前言 所谓骨架屏,就是在页面进行耗时加载时,先展示的等待 UI, 以告知用户程序目前正在运行,稍等即可。 等待的UI大部分是 loading 转圈的弹窗,有的是自己风格的小动画。其实…...

Ruoyi-Cloud-Plus_使用Docker部署分布式微服务系统_环境准备_001---SpringCloud工作笔记200

1.首先安装docker: 如果以前安装过首先执行: yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine 去卸载docker 2.安装dokcer需要的工具包…...

RN封装的底部向上弹出的弹出层组件

组件代码 import React from react; import { View, StyleSheet, Modal, TouchableOpacity, Text, TouchableWithoutFeedback } from react-native;const BottomPopup ({ visible, onClose, children, leftButtonTitle, rightButtonTitle, onLeftButtonPress, onRightButtonP…...

基于深度学习YOLOv8+PyQt5的水底海底垃圾生物探测器检测识别系统(源码+数据集+配置说明)

wx供重浩:创享日记 对话框发送:323海底 获取完整源码7000张数据集配置说明文件说明远程操作配置环境跑通程序 效果展示 基于深度学习YOLOv8PyQt5的水底海底垃圾生物探测器检测识别系统设计(源码数据集配置文件) 各文件说明 程序运…...

SpringBoot集成WebSocket实现简单的多人聊天室

上代码—gitee下载地址: https://gitee.com/bestwater/Spring-websocket.git下载代码,连上数据库执行SQL,就可以运行,最终效果...

如何使用固定公网地址远程访问内网Axure RP生成的网站原型web页面

文章目录 前言1.在AxureRP中生成HTML文件2.配置IIS服务3.添加防火墙安全策略4.使用cpolar内网穿透实现公网访问4.1 登录cpolar web ui管理界面4.2 启动website隧道4.3 获取公网URL地址4.4. 公网远程访问内网web站点4.5 配置固定二级子域名公网访问内网web站点4.5.1创建一条固定…...

蓝桥杯习题

https://www.lanqiao.cn/problems/1265/learning/ 第一题---排序 给定一个长度为N的数组A,请你先从小到大输出它的每个元素,再从大到小输出他的每个元素。 输入描述: 第一行包含一个整数N 第二行包含N个整数a1,a2,a3,...an,表…...

AMS概念以及面试相关整理

1、ActivityManagerService是什么?什么时候初始化的?有什么作用? ActivityManagerService(AMS)是什么? ActivityManagerService(简称AMS)是Android操作系统中的一个核心服务&#…...

Vmware下减小Ubuntu系统占用系统盘大小

1、虚拟机设置下占用空间 如图,给虚拟机分配了120GB,已经占用116.9GB,开机会提示空间不足。 2、实际使用空间 ubuntu系统下使用“df -h”命令查看实际使用空间大小50GB左右 造成这个原因是,虚拟机的bug:在虚拟机的ub…...

面试题-Elasticsearch集群架构和调优手段(超全面)

对于Elasticsearch(ES),我了解并有经验。在我之前的公司,我们有一个相对大型的ES集群,以下是该集群的架构和一些调优手段的概述: 1. 集群架构 集群规模:我们的ES集群由15个节点组成&#xff0c…...

<6>-MySQL表的增删查改

目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表&#xf…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...