Python进阶05-多线程

news2024/11/15 1:56:06

零、文章目录

Python进阶05-多线程

1、进程

(1)单任务
  • 单任务:指在同一时间内只执行单个任务。
import time

# 定义一个函数,用于实现听音乐
def music():
    for i in range(3):
        print('正在听音乐...')
        time.sleep(0.2)

# 定义一个函数,用于实现写代码
def coding():
    for i in range(3):
        print('正在写代码...')
        time.sleep(0.2)

# 定义一个程序执行的入口
if __name__ == '__main__':
    music()
    coding()
(2)多任务
  • 多任务:指在同一时间内执行多个任务。
  • 例如: 现在电脑安装的操作系统都是多任务操作系统,可以同时运行着多个软件。

image-20240821114918460

  • 多任务的两种表现形式

    • 并发:在一段时间内交替去执行多个任务。
    • 并行:在一段时间内真正的同时一起执行多个任务。
  • 并发案例

    • 对于单核cpu处理多任务,操作系统轮流让各个任务交替执行,假如:软件1执行0.01秒,切换到软件2,软件2执行0.01秒,再切换到软件3,执行0.01秒……这样反复执行下去 , 实际上每个软件都是交替执行的 . 但是,由于CPU的执行速度实在是太快了,表面上我们感觉就像这些软件都在同时执行一样 . 这里需要注意单核cpu是并发的执行多任务的。

    image-20240821145715583

  • 并行案例

    • 对于多核cpu处理多任务,操作系统会给cpu的每个内核安排一个执行的任务,多个内核是真正的一起同时执行多个任务。这里需要注意多核cpu是并行的执行多任务,始终有多个任务一起执行。

      image-20240821153338822

(3)进程
  • 进程(Process)是资源分配的最小单位,它是操作系统进行资源分配和调度运行的基本单位。一个程序运行后至少有一个进程。
  • 通俗理解:一个正在运行的程序就是一个进程 . 例如:正在运行的qq , 微信等 他们都是一个进程。
(4)多进程完成多任务
  • 多进程是Python程序中实现多任务的一种方式,使用多进程可以大大提高程序的执行效率 。

image-20240822222658006

(5)进程创建
  • 进程的创建步骤

    • 导入进程包:import multiprocessing
    • 通过进程类创建进程对象:进程对象 = multiprocessing.Process()
    • 启动进程执行任务:进程对象.start()
  • 通过进程类创建进程对象参数说明:进程对象 = multiprocessing.Process(target=任务名)

    • image-20240822222718690

    • import time
      # 第一步:导入多进程包
      import multiprocessing
      
      # 定义一个music()函数,用于实现听音乐功能
      def music():
          for i in range(3):
              print('正在听音乐...')
              time.sleep(0.2)
      
      # 定义一个coding()函数,用于实现写代码功能
      def coding():
          for i in range(3):
              print('正在写代码...')
              time.sleep(0.2)
      
      # 定义一个程序的执行入口
      if __name__ == '__main__':
          # ... 主进程
          # 第二步:在主进程中创建两个子进程
          music_process = multiprocessing.Process(target=music)
          coding_process = multiprocessing.Process(target=coding)
          # 第三步:启动刚才创建的子进程
          music_process.start()
          coding_process.start()
      
  • 进程执行带有参数的任务

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

    • args参数的使用

      • # target: 进程执行的函数名
        # args: 表示以元组的方式给函数传参
        sing_process = multiprocessing.Process(target=music, args=(3,))
        sing_process.start()
        
    • kwargs参数的使用

      • # target: 进程执行的函数名
        # kwargs: 表示以字典的方式给函数传参
        dance_process = multiprocessing.Process (target=coding, kwargs={“t": 0.2})
        # 启动进程
        dance_process.start()
        
    • 注意点:

      • 元组方式传参 :元组方式传参一定要和参数的顺序保持一致
      • 字典方式传参:字典方式传参字典中的key一定要和参数名保持一致
    • import time
      # 第一步:导入多任务包
      import multiprocessing
      
      # 定义一个music()函数,用于实现听音乐功能
      # 参数n代表循环次数
      def music(n):
          for i in range(n):
              print('正在听音乐...')
              time.sleep(0.2)
      
      # 定义一个coding()函数,用于实现写代码功能
      # 参数t代表休眠时间
      def coding(t):
          for i in range(3):
              print('正在写代码...')
              time.sleep(t)
      
      # 定义一个程序的执行入口
      if __name__ == '__main__':
          # 第二步:创建子进程对象
          music_process = multiprocessing.Process(target=music, args=(3,))
          coding_process = multiprocessing.Process(target=coding, kwargs={'t':0.2})
      
          # 第三步:启动子进程
          music_process.start()
          coding_process.start()
      
(6)获取进程编号
  • 进程编号的作用:当程序中进程的数量越来越多时 , 如果没有办法区分进程就无法进行有效的进程管理 , 为了方便管理使用进程编号。

  • 获取进程编号的两种方式 :

    • os.getpid():获取进程编号

      • import os
        pid = os.getpid()
        print(pid)
        # 或者
        import multiprocessing
        pid = multiprocessing.current_process().pid
        print(pid)
        
    • os.getppid():获取父进程编号

      • def work():
            # 查看当前进程
            current_process = multiprocessing.current_process()
            # 获取当前进程的编号
            print(“work进程编号:, current_process.pid, os.getpid())
            # 获取父进程的编号
            print(“work父进程的编号:, os.getppid())    
        
  • os.kill():杀死进程

    • '''
      import os
      
      os.kill(进程PID编号, 传递的信号)
      信号:
      9 : 强制杀掉PID进程
      15 :通知PID进程,正常结束
      '''
      import os
      
      os.kill(12752, 9)
      
(7)多进程之间不共享全局变量

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

  • 单任务中进程之间是可以共享变量的
'''
在单任务中,多个函数之间是可以共享全局变量的。
'''
import time

my_list = []

def write_data():
    for i in range(3):
        my_list.append(i)
        print('add:', i)
    print(my_list)

def read_data():
    print(my_list)

if __name__ == '__main__':
    write_data()# [0, 1, 2]
    time.sleep(1)
    read_data()# [0, 1, 2]
  • 多进程之间不共享全局变量
'''
在单任务中,多个函数之间是可以共享全局变量的。
在多进程多任务中,多个进程之间无法共享全局变量。
'''
import time
import multiprocessing

my_list = []

def write_data():
    for i in range(3):
        my_list.append(i)
        print('add:', i)
    print(my_list)

def read_data():
    print(my_list)

if __name__ == '__main__':
    # 创建子进程
    write_process = multiprocessing.Process(target=write_data)
    read_process = multiprocessing.Process(target=read_data)

    # 启动子进程
    write_process.start()#[0, 1, 2]
    time.sleep(1)
    read_process.start()#[]
(8)主进程和子进程的结束顺序
  • 默认情况:主进程会等待所有的子进程执行结束再结束

    • import time
      import multiprocessing
      
      # 定义一个work任务
      def work():
          for i in range(10):
              print('working...')
              time.sleep(0.2)
      
      # 定义一个入口程序
      if __name__ == '__main__':
          # 创建一个子进程(大约需要2s执行完毕)
          sub_process = multiprocessing.Process(target=work)
          sub_process.start()
      
          # 休眠1s
          time.sleep(1)
          print('主进程代码已经执行结束!')
      
      # 主进程代码执行结束后,整个程序并不会立即结束,而是等待子进程执行结束,当子进程执行结束后,整个主进程才能真正结束!
      # 结论:主进程默认会等待子进程的结束而结束
      
  • 设置守护进程:主进程退出后直接销毁子进程,不再等待执行子进程

    • import time
      import multiprocessing
      
      # 定义一个work任务
      def work():
          for i in range(10):
              print('working...')
              time.sleep(0.2)
      
      # 定义一个入口程序
      if __name__ == '__main__':
          # 创建一个子进程(大约需要2s执行完毕)
          sub_process = multiprocessing.Process(target=work)
          # 第一种解决方案:守护进程
          sub_process.daemon = True
          sub_process.start()
      
          # 休眠1s
          time.sleep(1)
          print('主进程代码已经执行结束!')
      
  • 手工销毁子进程:主进程退出后不再等待执行子进程

    • import time
      import multiprocessing
      
      # 定义一个work任务
      def work():
          for i in range(10):
              print('working...')
              time.sleep(0.2)
      
      # 定义一个入口程序
      if __name__ == '__main__':
          # 创建一个子进程(大约需要2s执行完毕)
          sub_process = multiprocessing.Process(target=work)
          sub_process.start()
      
          # 休眠1s
          time.sleep(1)
      
          # 在主程序结束之前,强制销毁子进程
          sub_process.terminate()
          print('主进程代码已经执行结束!')
      

2、线程

(1)线程
  • 线程:程序执行的最小单位 , 实际上进程只负责分配资源 , 而利用这些资源执行程序的是线程 , 也就说进程是线程的容器 , 一个进程中最少有一个线程来负责执行程序。
  • 线程自己不拥有系统资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。这就像通过一个QQ软件(一个进程)打开两个窗口(两个线程)跟两个人聊天一样 , 实现多任务的同时也节省了资源。
(2)多线程完成多任务
  • 多线程是Python程序中实现多任务的另一种方式。
    • image-20240823144212797
(3)线程创建
  • 线程的创建步骤

    • 导入线程模块:import threading
    • 通过线程类创建线程对象:线程对象 = threading.Thread(target=任务名)
    • 启动线程执行任务:线程对象.start()
  • 通过线程类创建线程对象

    • image-20240823144635148

    • '''
      在Python代码中,一个Python文件可以创建一个进程 => 创建多线程
      线程包含在进程内部,一个进程理论上最少有一个线程
      ① 进程资源分配最小单元 => 申请资源
      ② 线程专门用于执行程序(干活的)
      '''
      import time
      # 第一步:导入多线程模块
      import threading
      
      def music():
          for i in range(3):
              print('正在听音乐...')
              time.sleep(0.2)
      
      def coding():
          for i in range(3):
              print('正在写代码...')
              time.sleep(0.2)
      
      if __name__ == '__main__':
          # 第二步:创建多线程对象
          music_thread = threading.Thread(target=music)
          coding_thread = threading.Thread(target=coding)
      
          # 第三步:启动多线程
          music_thread.start()
          coding_thread.start()
      
  • 线程执行带有参数的任务

    • image-20240823160138826

    • args参数的使用

      • # target: 线程执行的函数名
        # args: 表示以元组的方式给函数传参
        coding_thread = threading.Thread(target=coding, args=(3,))
        coding_thread.start()
        
    • kwargs参数的使用

      • # target: 线程执行的函数名
        # kwargs: 表示以字典的方式给函数传参
        music_thread = threading.Thread(target=music, kwargs={”count": 3})
        # 开启线程
        music_thread.start()
        
    • 注意点

      • 元组方式传参 :元组方式传参一定要和参数的顺序保持一致
      • 字典方式传参:字典方式传参字典中的key一定要和参数名保持一致
    • '''
      在Python代码中,我们可以在多任务中使用args或kwargs进行传参
      args:以元组方式传递参数
      kwargs:以字典方式传递参数
      '''
      import time
      # 第一步:导入多线程模块
      import threading
      
      # 参数n代表循环次数
      def music(n):
          for i in range(n):
              print('正在听音乐...')
              time.sleep(0.2)
      
      # 参数t代表休眠时间
      def coding(t):
          for i in range(3):
              print('正在写代码...')
              time.sleep(t)
      
      if __name__ == '__main__':
          # 第二步:创建多线程对象
          music_thread = threading.Thread(target=music, args=(3,))
          coding_thread = threading.Thread(target=coding, kwargs={'t':0.2})
      
          # 第三步:启动多线程
          music_thread.start()
          coding_thread.start()
      
(4)线程间共享全局变量
  • 多个线程都是在同一个进程中 , 多个线程使用的资源都是同一个进程中的资源 , 因此多线程间是共享全局变量

    • image-20240825175850827

    • '''
      多进程实现多任务:无法共享全局变量
      多线程实现多任务:因为所有线程都位于同一个进程中,所以不仅资源共享,而且全局变量也是共享的
      '''
      import time
      import threading
      
      my_list = []
      
      # 定义一个write_data()任务
      def write_data():
          for i in range(3):
              my_list.append(i)
              print('add:', i)
          print(my_list)
      
      # 定义一个read_data()任务
      def read_data():
          print(my_list)
      
      if __name__ == '__main__':
          # 创建两个子线程
          write_thread = threading.Thread(target=write_data)
          read_thread = threading.Thread(target=read_data)
      
          write_thread.start() # [0, 1, 2]
          time.sleep(1)
          read_thread.start()  # [0, 1, 2]
      
(5)主线程和子线程的结束顺序
  • 默认情况:主线程会等待所有的子线程执行结束后主线程再结束

    • import time
      import threading
      
      def work():
          for i in range(10):
              print('working...')
              time.sleep(0.2)
      
      if __name__ == '__main__':
          # 创建一个子线程
          sub_thread = threading.Thread(target=work)
          # 启动子线程
          sub_thread.start()
      
          time.sleep(1)
          print('主线程代码执行结束!')
      
  • 设置守护进程:主进程退出后直接销毁子线程,不再等待执行子进程

    • import time
      import threading
      
      def work():
          for i in range(10):
              print('working...')
              time.sleep(0.2)
      
      if __name__ == '__main__':
          # 创建一个子线程
          # 方案一:守护主线程
          # sub_thread = threading.Thread(target=work, daemon=True)
          # 方案二:通过方法设置守护主线程
          sub_thread = threading.Thread(target=work)
          sub_thread.setDaemon(True)
      
          # 启动子线程
          sub_thread.start()
      
          time.sleep(1)
          print('主线程代码执行结束!')
      
(6)线程间的执行顺序
  • 线程之间执行是无序的,是由CPU调度决定某个线程先执行的

image-20240825182711319

  • 同时启动多个线程
'''
要用到的知识点:获取进程的信息
# 通过current_thread方法获取线程对象
current_thread = threading.current_thread()
# 通过current_thread对象可以知道线程的相关信息,例如被创建的顺序
print(current_thread)
'''
import time
import threading

def get_info():
    time.sleep(0.2)
    current_thread = threading.current_thread()
    print(current_thread)


if __name__ == '__main__':
    # 创建10个子线程 => 按顺序创建
    for i in range(10):  # 0 1 2 3 4 5 6 7 8 9
        sub_thread = threading.Thread(target=get_info)
        sub_thread.start()
  • 输出是乱序的
<Thread(Thread-3 (get_info), started 10936)>
<Thread(Thread-2 (get_info), started 4516)>
<Thread(Thread-1 (get_info), started 15400)>
<Thread(Thread-8 (get_info), started 10928)>
<Thread(Thread-7 (get_info), started 7676)>
<Thread(Thread-6 (get_info), started 13376)>
<Thread(Thread-4 (get_info), started 3344)>
<Thread(Thread-5 (get_info), started 4912)>
<Thread(Thread-10 (get_info), started 12508)>
<Thread(Thread-9 (get_info), started 7908)>

3、进程VS线程

(1)关系对比
  • ① 线程是依附在进程里面的,没有进程就没有线程。

  • ② 一个进程默认提供一条线程,进程可以创建多个线程。

(2)区别对比
  • ① 进程之间不共享全局变量

  • ② 线程之间共享全局变量

  • ③ 创建进程的资源开销要比创建线程的资源开销要大

  • ④ 进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位

(3)优缺点对比
  • ① 进程优缺点

    • 优点:可以用多核,适合CPU密集型应用

    • 缺点:资源开销大

  • ② 线程优缺点

    • 优点:资源开销小,适合IO密集型应用(文件、网络)

    • 缺点:不能使用多核

4、TCP服务器端开发七步走(多任务版本)

'''
TCP服务器端开发七步走 => ① 创建套接字对象 ② 绑定IP和端口 ③ 设置监听 ④ 接收客户端连接请求 ⑤ 接收消息
⑥ 发送消息 ⑦ 关闭套接字对象
'''
import socket
import threading

class WebServer(object):
    # 3、定义一个__init__()魔术方法
    def __init__(self):
        self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置端口复用(让服务器端占用的端口在执行结束可以立即释放,不影响后续程序的使用)
        self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.tcp_server_socket.bind(('', 9000))  # 注意:参数必须是一个元组
        self.tcp_server_socket.listen(128)

    # 5、定义一个handle_request()方法,用于接收消息与发送消息
    def handle_request(self, new_socket, ip_port):
        # 接收某个客户端发送过来的消息
        content = new_socket.recv(1024).decode('gbk')  # 1024代表什么意思 => 1024字节 => 1kb = 实际工作中,一条数据大小在1~1.5k之间
        print(f'{ip_port}客户端发送消息:{content}')
        # 返回数据给客户端
        new_socket.send('信息已收到,over!'.encode('gbk'))
        # 关闭套接字对象
        # new_socket.close()

    # 4、定义一个start()方法
    def start(self):
        while True:
            new_socket, ip_port = self.tcp_server_socket.accept()
            # 来一个客户,我们就为其创建一个线程,调用自身的handle_request()方法,用于接收消息与发送消息
            sub_thread = threading.Thread(target=self.handle_request, args = (new_socket, ip_port))
            # 启动线程
            sub_thread.start()

# 定义一个程序的执行入口
if __name__ == '__main__':
    # 1、实例化对象
    ws = WebServer()
    # 2、调用对象中的相关方法 => 启动TCP服务
    ws.start()

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

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

相关文章

振弦式基岩位移计主要功能探析

在土木工程和地质监测领域&#xff0c;基岩位移计作为一种重要的监测设备&#xff0c;发挥着不可替代的作用。其主要功能在于长期、精准地测量水工结构物、桥梁、建筑、铁路等混凝土结构物与地基之间的开合度(位移)&#xff0c;并同步监测埋设点的温度变化。本文将深入探讨基岩…

【漏洞复现】某联云采 SRM2.0 download 任意文件读取漏洞

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 某联云采 SRM2.0 是一款专门为企业供应链管理设计的采购管理系统。它具备采购流程自动化、供应商管理优化…

LLM大模型入门天花板!《大模型入门:技术原理与实战应用》一本书让你轻松入门大模型(附PDF)

随着大模型技术的不断完善和普及&#xff0c;我们将进入一个由数据驱动、智能辅助的全新工作模式和生活模式。个人和企业将能够利用大模型来降本增效&#xff0c;并创造全新的用户体验。 人工智能是人类探索未来的重要领域之一&#xff0c;以GPT为代表的大模型应用一经推出在短…

【网络安全】服务基础第一阶段——第二节:Windows系统管理基础----虚拟化IP地址以及用户与组管理

目录 一、Windows网络测试工具 1.1.ping命令 1.2.tracert命令 二、IP实验内容 2.1 实验一 2.2 实验二 三、用户与组管理 3.1 用户与账户概述 3.2 用户管理 3.3 用户增删改查 3.4 增加用户 3.5 修改用户属性 3.6 删除用户 3.7 组账户概述 3.8 组账户增删改查 四、…

linux网络编程-原理到应用-附源码(全)

目录 一、计算机网络分层模型 1.1 概念 1.2 OSI 七层模型 1.3 五层模型 1.4 TCP/IP四层模型 二、传输层-TCP协议 2.1 什么是TCP协议&#xff1f; 2.2 TCP的连接的建立和释放 2.3 基于TCP协议-只接受一个连接的范例程序 一、计算机网络分层模型 1.1 概念 计算机网络…

装过mr又卸载了,max报错 mrmateralattribs missing dlls

rendering>scene converter 打开对话框后&#xff0c;current preset 中选择 remove invalid legacy elements&#xff0c;取消open scene converter。。勾选 automaticaly remove missing。再点 convet scene

HTML静态网页成品作业(HTML+CSS)——个人介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

java-Spring框架02

1.AOP 1.概述 AOP &#xff08;Aspect Oriented Programming&#xff09;&#xff1a;面向切面编程&#xff0c;通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。&#xff08;是对面向对象编程的补充延续&#xff0c;&#xff09; 面向切面编程思想&#…

Linux之ip命令详解

华子目录 1.ip命令是什么1.1ip命令的由来1.2ip命令的安装包1.2ip选项&#xff08;基本不用&#xff09; 2.查看网络信息2.1显示全部网络接口信息2.2显示单个网络接口信息2.3显示单个接口状态2.4查看路由表2.5查看arp缓存 3.设置网卡ip地址3.1启用或停用网卡3.2设置默认网关3.3新…

【数据集】遥感影像建筑物提取论文常用数据集

几个常用于遥感影像建筑物对比试验的数据集 WHU building dataset 下载链接&#xff1a; https://study.rsgis.whu.edu.cn/pages/download/building_dataset.html WHU数据集中包含多个子数据集&#xff1a; Aerial imagery dataset 航空影像建筑物数据集 数量&#xff1a;8…

SD3337C 恒流Boost DC/DC转换器的白色LED驱动器芯片IC

一般描述 SD3337C是一款升压型DC/DC转换器&#xff0c;具有恒定电流&#xff0c;可驱动白色LED或类似器件。该 器件可以从锂离子电池驱动多达八个串联的LED。LED电流由外部电阻器(RsET)设置&#xff0c;并由反馈(FB)电压(典型值:200mV)直接调节&#xff0c;该电压跨接在…

IntelliJ IDEA使用内网穿透工具配置的公网地址远程连接本地MySQL

文章目录 前言1. 本地连接测试2. Windows安装Cpolar3. 配置Mysql公网地址4. IDEA远程连接Mysql5. 固定连接公网地址6. 固定地址连接测试 前言 本教程主要介绍如何使用Cpolar内网穿透工具实现在IDEA中也可以远程访问家里或者公司的数据库&#xff0c;提高开发效率&#xff01;无…

Stable Diffusion 使用详解(9)--- 字体及背景融入

目录 背景 方法一 利用controlNet lineart invert depth 提示词 效果 方法二 准备蒙版 绘制大型场景艺术字 controlnet Lora 模型 效果 PS 融入 背景 如果看过上一期你应该知道如何利用layer diffusion 制作场景动漫海报&#xff0c;其实掌握这个方法后&#xf…

Java 入门指南:初识 Java NIO

NIO 的引入 在传统的 Java I/O 模型&#xff08;BIO&#xff09;中&#xff0c;I/O 操作是以阻塞的方式进行的。当一个线程执行一个 I/O 操作时&#xff0c;它会被阻塞直到操作完成。这种阻塞模型在处理多个并发连接时可能会导致性能瓶颈&#xff0c;因为需要为每个连接创建一…

【Three.js基础学习】20.Environment map

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 课程回顾&#xff1a; 模型的加载 GLTFLoader 环境贴图实现&#xff1b; CubeTextureLoader LDR:低动态范围 backgroundBlurriness&#xff1a;设置背景模糊 (不生效 为…

CSND文章质量分批量查询

简介 CSDN 质量分是一项公开的 CSDN 博文内容质量分析服务&#xff0c;其综合分析了内容的标题、段落结构、正文长度、代码格式及复杂度、链接和超文本内容比例及质量等因素&#xff0c;为 IT 技术文章提供客观公共的质量分析结果 用途 可用与对文章质量做评估可申请创作者 …

更新RK3588开发板的rknn_server和librknnrt.so【这篇文章是RKNPU2从入门到实践 --- 【5】的配套文章】

作者使用的平台有&#xff1a; 一台装有Windows系统的宿主机&#xff0c;在该宿主机上装有Ubuntu 20.04虚拟系统&#xff1b; 瑞芯微RK3588开发板&#xff0c;开发板上的系统为Ubuntu22.04系统&#xff1b; 更新板子的 rknn_server 和 librknnrt.so&#xff0c;rknn_server 和…

Facebook AI的应用前景:如何利用人工智能提升平台功能

人工智能&#xff08;AI&#xff09;正迅速改变我们与社交网络互动的方式。作为全球领先的社交媒体平台之一&#xff0c;Facebook&#xff08;现Meta&#xff09;正通过多种AI技术提升其平台功能。本文将探讨Facebook AI的应用前景&#xff0c;展示如何利用这些技术优化用户体验…

OHIF Viewers 项目介绍

项目结构 项目架构 │ ├── extensions │ ├── default # 默认功能 │ ├── cornerstone # 使用 Cornerstonejs 处理 2D/3D 图像 │ ├── cornerstone-dicom-sr # 结构化报告 (DICOM SR) │ ├── measurement-tracking # 测量追…

备战秋招60天算法挑战,Day28

题目链接&#xff1a; https://leetcode.cn/problems/climbing-stairs/ 视频题解&#xff1a; https://www.bilibili.com/video/BV1h1421t7W3/ LeetCode 70.爬楼梯 题目描述 假设你正在爬楼梯。需要n阶你才能到达楼顶。 每次你可以爬1或2个台阶。你有多少种不同的方法可以爬到…