Python:Python编程:从入门到实践__超清版:Python标准库:线程

news2025/1/13 7:40:57

Python线程与安全

    • 实现线程安全有多重方式,常见的包括:锁,条件变量,原子操作,线程本地存储等。 💚
  • 1. 锁
  • 2. 条件变量
  • 3. 通过 join 阻塞当前线程
  • 4. 采用 sleep 来休眠一段时间
  • 5. 原子操作
  • 5.1 使用 threading.Lock( ) 替代 atomic 原子操作
  • 6. 使用 threading.Local实现
  • 总结
  • 代码示例

线程安全是指:多线程并发访问共享资源时,不会导致数据的错误或不一致性,在多线程编程中,由于多个线程同时访问共享数据,那么这就可能导致数据竞争,死锁等问题。线程安全的实现是为了 避免这些问题的发生。

实现线程安全有多重方式,常见的包括:锁,条件变量,原子操作,线程本地存储等。
💚

1. 锁

锁是一种 常见的线程同步机制,用于控制对共享资源的访问,在 Python中,锁有两种类型:互斥锁和 读写锁。互斥锁在同一时刻只允许一个线程对共享数据进行操作,读写锁则允许 多个线程同时读取共享数据,但是只允许 一个线程进行写操作。

可以使用 threading.Lock() 或 threading.RLock() 来创建互斥锁或读写锁

下面这个例子:新建 5个线程,和一个全局变量,然后每个线程在 start() 后,会调用 线程的 run(self) 函数,该函数会将变量 自增10 , 通过 lock 锁,可以实现 变量读写安全。
class myThread(threading.Thread):
    def run(self):
        global x  # 声明一个共享数据 x
        lock.acquire() # 上锁
        x += 10  # 变量x 增加10
        print('%s: %d' %(self.name,x)) # self 是线程对象,可以通过selt.name 得到线程名
        lock.release() #解锁
       
# 设置全局变量 x 
x = 0
lock = threading.RLock() # 创建可置入锁
list_thread = []
for i in range(5):
    list_thread.append(myThread()) # 创建5个线程,放到同一列表中

for i in list_thread:
 	i.start()  # 开启线程

# 打印
Thread-1: 10
Thread-2: 20
Thread-3: 30
Thread-4: 40
Thread-5: 50

2. 条件变量

  条件变量时一种用于线程间通信的同步机制,用于在多个线程之间共享状态信息,以便线程可以等待某个条件的出现并被通知,通常情况下,一个线程会等待另一个线程 触发某个条件,当条件满足时,等待的线程被通知并继续执行。
  在Python 中,条件变量是通过 threading.Condition类实现的,Condition 类实际上是一个 锁对象,它允许多个线程等待某个条件的出现,当条件满足时,Condition 会自动通知等待的线程继续执行,可以使用 condition 对象的 wait( ) 方法使 线程等待某个条件的出现,使用 notify()  或者 notify_all( )  方法通知等待的线程。

💚 下面我通过一个生成者和消费者模型来说明

举例:如有几个生产车间,几个消费者,当生产到一定数量时,即可停止生产。

# 举例:有几个生产车间,几个消费者,当生产到一定数量时,即可停止生产
condition = threading.Condition() # 获取线程条件锁
sheep = ['1件产品','1件产品','1件产品','1件产品','1件产品','1件产品']
class Producer(threading.Thread):
    def __init__(self,name):
        super().__init__(name = name)
        pass
    def run(self):
        global condition,sheep
        while True:
            time.sleep(0.1)
            condition.acquire()  # 上锁
            if len(sheep) < 10:
                print(self.name + "生产了1件产品")
                sheep.append('1件产品')
                condition.notifyAll()
                pass
            else:
                print("仓库满了,请停止生产,并等待5s后生产")
                condition.wait()
                time.sleep(5)
                pass
            condition.release()
        pass
    pass
 
class Custome(threading.Thread):
    def __init__(self,name):
        super().__init__(name = name)
        pass
    def run(self):
        global condition,sheep
        while True:
            time.sleep(0.1)
            condition.acquire()
            if len(sheep) > 0:
                meat = sheep.pop()
                print(self.name + "购买了" + meat + ",还剩" + str(len(sheep)) + "件")
                condition.notifyAll
                pass
            else:
                print("对不起,买光了,请等待5s后再购买")
                condition.wait()
                time.sleep(5)
                pass
            condition.release()
        pass
    pass
    
p1 = Producer("1号生产车间")
p2 = Producer("2号生产车间")
p3 = Producer("3号生产车间")
p4 = Producer("4号生产车间")
p5 = Producer("5号生产车间")

p1.start()
p2.start()
p3.start()
p4.start()
p5.start()

c1 = Custome("小王")
c2 = Custome("小张")
c3 = Custome("小刘")
c4 = Custome("小李")

c1.start()
c2.start()
c3.start()
c4.start()    

在这里插入图片描述

3. 通过 join 阻塞当前线程

import threading
def thread_test(x,y):
    for i in range(x,y): # range函数 :生成一系列连续整数的函数
        print(i)

thread_01 = threading.Thread(name = 't1',target = thread_test,args=(1,50))
thread_02 = threading.Thread(name = 't2',target = thread_test,args=(11,20))

thread_01.start() # 启动线程1
thread_01.join() # 阻塞主线程,让线程thread_01 执行完毕后再执行后面的代码
print ("thread_01 run over")
print ("main thread ----!")
thread_02.start() # 启动线程2 
thread_02.join()
print ("thread_02run over")

// 打印结果
1
2
3
4
5
6
7
8
9
thread_01 run over
main thread ----!
11
12
13
14
15
16
17
18
19
thread_02run over

4. 采用 sleep 来休眠一段时间

# 方法2:通过 sleep来休眠当前线程

import time
import threading
def thread_sleep(x,y):
    print("子线程开始休眠 10s")
    time.sleep(10)  # 休眠10s
    print("子线程休眠结束")
    for i in range(x,y): # range函数 :生成一系列连续的函数
        print(i)
    print("子线程执行完毕")

thread_03 = threading.Thread(target = thread_sleep,daemon = False,args=(1,5)) #线程不会随着主线程退出而退出
thread_03.start()
print("主线线程执行完毕")  

# 打印结果
子线程开始休眠 10s
主线线程执行完毕
子线程休眠结束
1
2
3
4
子线程执行完毕

5. 原子操作

Python的 atmoic 模块提供了一种机制:来确保可与多线程并发使用的函数原子性,它实现了一个 锁机制,该锁机制可保证同一时刻只有一个线程能够访问指定的函数。

🧡🧡🧡 使用 atmoic 模块有以下步骤

  1. 导入atmoic 模块
    import atmoic
  2. 创建一个 atmoic.Atmoic 对象 用于同步访问
    lock = atmoic.Atmoic()
  3. 将需要的原子性操作代码包裹在 lock.atmoic( ) 中
    with lock.atmoic():

💚 举例 :我们可以使用 atmoic 模块确保两条线程能够同步递增一个计数器

# 在此示例中,我们在increment()函数内使用了lock.atomic()来确保任何时刻仅有一条线程能够访问计数器。
# 这样,即使多个线程同时执行increment()函数在计数器上进行递增,结果也将是唯一且正确的。在本例中,最终输出的计数器值将为2。

# 但是 atomic 这个库下载失败
# 1.通过清华教育镜像会下载失败
#2. 通过 https://pypi.org/project/atomic/ 页面中下载源代码 然后通过:pip install /path/to/atomic-x.x.x.tar.gz 也安装失败
# 3. PATHONPATH 已经安装
# 4. 怀疑是和C++环境冲突了
import atomic
count = 0
lock = atmoic.Atmoic()
def increment():
    global count
    with lock.atmoic():
        count += 1
        
# 创建三条线程并启动他们
thread_01 = threading.Thread(target = increment)
thread_02 = threading.Thread(target = increment)
thread_03 = threading.Thread(target = increment)

thread_01.start()
thread_02.start()
thread_03.start()

#等待三条线程执行完毕
thread_01.join()
thread_02.join()
thread_03.join()

# 输出3
print('count: ',count) 

5.1 使用 threading.Lock( ) 替代 atomic 原子操作

value = 0
lock = threading.Lock()

def atomic_add(num):
    global value
    with lock:
        value += num

# 示例运行代码
for i in range(10):
    t = threading.Thread(target=atomic_add, args=(1,))
    t.start()
    t.join()
print(value)  # 结果应为10

说明:
#在上述代码中,使用了 Python 中的线程锁来保证 value 变量的原子性。每个线程都会执行一次 atomic_add 函数,
# 其中使用了 with lock 语句来获取线程锁,确保在执行某个线程操作 value 时,没有其他线程在执行这个操作。
#如果你需要更高效的 atomic add 实现,可以考虑使用 ctypes 库,利用 C 语言函数来实现原子操作。

在这里插入图片描述

6. 使用 threading.Local实现

💚

  1. threading.local()这个方法的特点用来保存一个全局变量,但是这个全局变量只有在当前线程才能访问,
    localVal.val = name这条语句可以储存一个变量到当前线程,如果在另外一个线程里面再次对localVal.val进行赋值,
    那么会在另外一个线程单独创建内存空间来存储,也就是说在不同的线程里面赋值 不会覆盖之前的值,因为每个

  2. 线程里面都有一个单独的空间来保存这个数据,而且这个数据是隔离的,其他线程无法访问

  3. 这个东西可以用在那些地方呢,比如下载,现在都是多线程下载了,就像酷狗那样,可以同时下载很多首歌曲,那么
    就可以利用这个方法来保存每个下载线程的数据,比如下载进度,下载速度之类的

import threading  
# 创建全局ThreadLocal对象:
localVal = threading.local()
localVal.val = "Main-Thread"
def process_student():
	print ('%s (in %s)' % (localVal.val,threading.current_thread().name))
    
#赋值
def process_thread(value): 
    localVal.val = value
    process_student()

# name = '定义线程名'    
t1 = threading.Thread(target =process_thread, args = ('One',), name = 'Thread-B')

t2 = threading.Thread(target =process_thread, args = ('Two',), name = 'Thread-A')

t1.start()
t2.start()
t1.join()
t2.join()

print (localVal.val)

# 打印结果
One (in Thread-B)
Two (in Thread-A)
Main-Thread

总结

  1. Python的线程操作在旧版本中使用的是thread模块,在Python27和Python3中引入了threading模块,同时thread模块在Python3中改名为_thread模块。
  2. threading模块相较于thread模块,对于线程的操作更加的丰富,而且threading模块本身也是相当于对thread模块的进一步封装而成,thread模块有的功能threading模块也都有,所以涉及到对线程的操作,推荐使用threading模块。
  3. threading模块中包含了关于线程操作的丰富功能,包括:常用线程函数,线程对象,锁对象,递归锁对象,事件对象,条件变量对象,信号量对象,定时器对象,栅栏对象。

代码示例

# python多线程
# 1:多线程基础
#或者
# 2:线程同步
#2.1 python的锁


# 方法1:通过 thread.join() 阻塞当前线程来实现
import threading
def thread_test(x,y):
    for i in range(x,y): # range函数 :生成一系列连续整数的函数
        print(i)

thread_01 = threading.Thread(name = 't1',target = thread_test,args=(1,10))
thread_02 = threading.Thread(name = 't2',target = thread_test,args=(11,20))

thread_01.start() # 启动线程1
thread_01.join() # 阻塞主线程,让线程thread_01 执行完毕后再执行后面的代码
print ("thread_01 run over")
print ("main thread ----!")
thread_02.start() # 启动线程2 
thread_02.join()
print ("thread_02run over")

# 方法2:通过 sleep来休眠当前线程

import time
def thread_sleep(x,y):
    print("子线程开始休眠 10s")
    time.sleep(10)  # 休眠10s
    print("子线程休眠结束")
    for i in range(x,y): # range函数 :生成一系列连续的函数
        print(i)

thread_03 = threading.Thread(target = thread_sleep,daemon = False,args=(20,50)) #线程不会随着主线程退出而退出
thread_03.start()
print("主线线程执行完毕")  
print("子线程执行完毕")


# 线程同步 
# python 的锁 :
# 背景:异步模式的情况下,同时有一个线程在修改共享数据,另一个线程在读取共享数据,当修改的共享数据的线程没有处理完毕,读取数据的线程肯定会得到错误的结果。
# 如果采用多线程的同步控制机制,当处理共享数据的线程完成处理数据之后,读取线程就读取数据。
# 1. 

# 举例
class myThread(threading.Thread):
    def run(self):
        global x  # 声明一个共享数据 x
        lock.acquire() # 上锁
        x += 10  # 变量x 增加10
        print('%s: %d' %(self.name,x)) # self 是线程对象,可以通过selt.name 得到线程名
        lock.release() #解锁
        

#设置全局变量 x 
x = 0
lock = threading.RLock() # 创建可置入锁
list_thread = []
for i in range(5):
    list_thread.append(myThread()) # 创建5个线程,放到同一列表中

for i in list_thread:
    i.start()  # 开启线程
        
        

# 举例:有几个生产车间,几个消费者,当生产到一定数量时,即可停止生产
condition = threading.Condition() # 获取线程条件锁
sheep = ['1件产品','1件产品','1件产品','1件产品','1件产品','1件产品']
class Producer(threading.Thread):
    def __init__(self,name):
        super().__init__(name = name)
        pass
    def run(self):
        global condition,sheep
        while True:
            time.sleep(0.1)
            condition.acquire()  # 上锁
            if len(sheep) < 10:
                print(self.name + "生产了1件产品")
                sheep.append('1件产品')
                condition.notifyAll()
                pass
            else:
                print("仓库满了,请停止生产,并等待5s后生产")
                condition.wait()
                time.sleep(5)
                pass
            condition.release()
        pass
    pass
 
class Custome(threading.Thread):
    def __init__(self,name):
        super().__init__(name = name)
        pass
    def run(self):
        global condition,sheep
        while True:
            time.sleep(0.1)
            condition.acquire()
            if len(sheep) > 0:
                meat = sheep.pop()
                print(self.name + "购买了" + meat + ",还剩" + str(len(sheep)) + "件")
                condition.notifyAll
                pass
            else:
                print("对不起,买光了,请等待5s后再购买")
                condition.wait()
                time.sleep(5)
                pass
            condition.release()
        pass
    pass
    
p1 = Producer("1号生产车间")
p2 = Producer("2号生产车间")
p3 = Producer("3号生产车间")
p4 = Producer("4号生产车间")
p5 = Producer("5号生产车间")

#p1.start()
#p2.start()
#p3.start()
#p4.start()
#p5.start()

c1 = Custome("小王")
c2 = Custome("小张")
c3 = Custome("小刘")
c4 = Custome("小李")

#c1.start()
#c2.start()
#c3.start()
#c4.start()    

import time
import threading
def thread_sleep(x,y):
    print("子线程开始休眠 10s")
    time.sleep(10)  # 休眠10s
    print("子线程休眠结束")
    for i in range(x,y): # range函数 :生成一系列连续的函数
        print(i)
    print("子线程执行完毕")

thread_03 = threading.Thread(target = thread_sleep,daemon = False,args=(1,5)) #线程不会随着主线程退出而退出
thread_03.start()
print("主线线程执行完毕")  


value = 0
lock = threading.Lock()

def atomic_add(num):
    global value
    with lock:
        value += num

# 示例运行代码
for i in range(10):
    t = threading.Thread(target=atomic_add, args=(1,))
    t.start()
    t.join()
print(value)  # 结果应为10

#在上述代码中,使用了 Python 中的线程锁来保证 value 变量的原子性。每个线程都会执行一次 atomic_add 函数,
#其中使用了 with lock 语句来获取线程锁,确保在执行某个线程操作 value 时,没有其他线程在执行这个操作。


#如果你需要更高效的 atomic add 实现,可以考虑使用 ctypes 库,利用 C 语言函数来实现原子操作。

# 在此示例中,我们在increment()函数内使用了lock.atomic()来确保任何时刻仅有一条线程能够访问计数器。
# 这样,即使多个线程同时执行increment()函数在计数器上进行递增,结果也将是唯一且正确的。在本例中,最终输出的计数器值将为2。

# 但是 atomic 这个库下载失败
# 1.通过清华教育镜像会下载失败
#2. 通过 https://pypi.org/project/atomic/ 页面中下载源代码 然后通过:pip install /path/to/atomic-x.x.x.tar.gz 也安装失败
# 3. PATHONPATH 已经安装
# 4. 怀疑是和C++环境冲突了


# import atomic
# count = 0
#lock = atmoic.Atmoic()
#def increment():
    # global count
    # with lock.atmoic():
      #  count += 1
        
# 创建三条线程并启动他们
#thread_01 = threading.Thread(target = increment)
#thread_02 = threading.Thread(target = increment)
#thread_03 = threading.Thread(target = increment)

#thread_01.start()
#thread_02.start()
#thread_03.start()

#等待三条线程执行完毕
#thread_01.join()
#thread_02.join()
#thread_03.join()

# 输出3
# print('count: ',count) 


#coding = utf - 8
import threading  
# 创建全局ThreadLocal对象:
localVal = threading.local()
localVal.val = "Main-Thread"
def process_student():
	print ('%s (in %s)' % (localVal.val,threading.current_thread().name))
    
#赋值
def process_thread(value): 
    localVal.val = value
    process_student()

# name = '定义线程名'    
t1 = threading.Thread(target =process_thread, args = ('One',), name = 'Thread-B')

t2 = threading.Thread(target =process_thread, args = ('Two',), name = 'Thread-A')

t1.start()
t2.start()
t1.join()
t2.join()

print (localVal.val)

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

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

相关文章

【I2C】Linux I2C子系统分析

文章目录 一、I2C体系架构二、主要的结构体1. i2c_adapter2. i2c_algorithm3. i2c_driver4. i2c_client4.1 方式一&#xff1a;通过I2C bus number静态方式来创建4.2 方式二&#xff1a;通过Device Tree来创建4.3 方式三&#xff1a;直接通过i2c_new_device来创建4.3 方式四&am…

openEuler22.03制作openstack平台使用的镜像

系列文章目录 第一章 openEuler22.03制作openstack平台使用的镜像 文章目录 系列文章目录前言一、virt-manager上的准备工作1、网卡类型切换为virtio2、IDE驱动设置成Virtio3、Display设置成vnc3、虚拟机系统分区 二、安装普通工具包三、安装云化工具包1、安装工具包2、修改配…

数字化转型,企业为什么要转型?如何转型?

数字化转型是利用数字化技术&#xff08;例如云计算、大数据、人工智能、物联网、区块链等&#xff09;和能力来驱动组织商业模式创新和商业生态系统重构的途径和方法即是数字化转型。其目的是实现企业业务的转型、创新、增长。 核心强调了两点&#xff0c;其一是数字化技术的应…

每日一练 | 华为认证真题练习Day51

1、如下图所示&#xff0c;IPSec传输模式中AH的头部应该插入到以下哪个位置&#xff1f; A. 1 B. 2 C. 3 D. 4 2、以下哪种远程登录方式最安全&#xff1f; A. Telnet B. Stelnet v100 C. Stelnet v2 D. Stelnet v1 3、以下业务模块的ACL默认动作为permit的是&#xff1…

玩转 ChatGPT,看这条就够了,Prompt 最全中文合集

Prompt 最全中文合集 玩转 ChatGPT&#xff0c;看这条就够了&#xff01; &#x1f680; 简化流程&#xff1a;ChatGPT Shortcut 提供了快捷指令表&#xff0c;可以快速筛选和搜索适用于不同场景的提示词&#xff0c;帮助用户简化使用流程。 &#x1f4bb; 提高生产力&#…

CSDN打出各种数学符号和数学公式

目录 1、基本四则运算2、指数对数3、根号、省略号、向量4、大&#xff08;小&#xff09;于等于号5、特殊符号、希腊字母符号6、累加累乘7、矩阵8、更改公式中的颜色 我们在用CSDN打出各种数学符号和数学公式时&#xff0c;需要学习一些关于LaTex的语法&#xff0c;在此做一个记…

java数组学习

一、数组的概述 1.数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合&#xff0c; 并使用一个名字命名&#xff0c;并通过编号的方式对这些数据进行统一管理。 2.数组相关的概念: >数组名 >元素 >角标、下标、索引 >数组的长度&#xff1a;元素…

联通云数据库CUDB:基于openGauss打造新一代自主创新云原生数据库

总体概述 联通云彰显央企担当&#xff0c;围绕国家对信息技术基础软件的政策要求&#xff0c;开展数据库自主研发。在openGauss开源社区版软件基础上&#xff0c;聚焦政企市场&#xff0c;坚持内核创新&#xff0c;完善工具生态&#xff0c;基于海量云存储能力、存算分离架构…

React中的懒加载以及在Ice中实践

您好&#xff0c;如果喜欢我的文章&#xff0c;可以关注我的公众号「量子前端」&#xff0c;将不定期关注推送前端好文~ 前言 对于页面性能优化&#xff0c;组件懒加载是个比较不错的方案&#xff0c;并且在整个项目打包后&#xff0c;如果未做代码分割&#xff0c;构建出的文…

代理ip的优势、用途及注意事项

随着互联网的高速发展&#xff0c;代理ip的名气和地位也随着水涨船高。那么是什么让它们被我们所知悉的呢&#xff1f;下面我们就代理ip的优势、用途和注意事项来分析一下它为什么能迎合着互联网的发展而壮大自己的。 一、优势 每一个脱颖而出的产品必然有它的优势&#xff0c;…

Axure教程—菜单(中继器)

本文将教大家如何用AXURE中的中继器制作菜单&#xff08;自动折叠其他菜单&#xff09; 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://iuek50.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87854640?spm1001.2014.30…

知识图谱简介

什么是知识图谱&#xff1f; 参考&#xff1a;知识图谱1、知识图谱2 本质上&#xff0c;知识图谱主要目标是用来描述真实世界中存在的各种实体和概念&#xff0c;以及他们之间的关系&#xff0c;因此可以认为是一种语义网络。 主要作用&#xff1a;通过数据&#xff0c;建立图…

智能自动化助力业务升级:探究低代码开发和业务流程自动化

当我们开始探索业务流程自动化&#xff08;BPA&#xff09;时&#xff0c;就证明我们已经真正进入到企业数字化转型的核心领域了——企业越来越关注如何通过创新技术来提高效率、降低成本并实现业务流程的自动化。在这个背景下&#xff0c;低代码开发平台和业务流程自动化成为了…

vue 滚动加载

在 Vue中&#xff0c;如果一个组件是一个 button&#xff0c;那就可以直接调用 input &#xff08;&#xff09;方法&#xff0c;将组件的 button放入到v-ui中。 然而在v-ui中&#xff0c;一个组件可能不止一个 button&#xff0c;而这些 button还需要从浏览器加载到 DOM树中。…

一个投喂ChatGPT大内容的小技巧

大家好&#xff0c;我是五竹。心血来潮整理了一份手册&#xff1a;《ChatGPT学习指南》并且将为小白们持续更新和GPT相关的资源和教程&#xff0c;专注于打造一部最好的GPT入门指南&#xff0c;欢迎大家转发、收藏、点赞支持&#xff01;谨防失联&#xff01; 至今还有很多人都…

渗透测试适合小白学习吗会让人感觉到无聊吗?

渗透测试是一项复杂的技能&#xff0c;需要具备扎实的计算机知识&#xff0c;对网络和系统安全有深入的理解和认识。对于初学者来说&#xff0c;建议先学习计算机网络、操作系统、编程语言等相关基础知识&#xff0c;了解渗透测试的概念、流程和常用工具。同时&#xff0c;需要…

HMR API及其原理

很久之前&#xff0c;遇到一个面试题&#xff1a;【在代码变更之后&#xff0c;如何实时看到更新后的页面效果呢&#xff1f;】 在传统的方案中&#xff0c;我们可以通过 live reload 也就是自动刷新页面的方式来解决的&#xff0c;不过随着前端工程的日益庞大&#xff0c;开发…

CSS3+HTML5

1、HTML5 2、HTML5标签 链接标签 <a href"https://www.baidu.com">打开百度&#xff0c;你就知道&#xff01;</a> 链接的属性与作用 属性1&#xff1a;href 作用&#xff1a;用于指定链接目标的url地址&#xff0c;当为标签应用href属性时…

(2022,DynamicD)使用动态鉴别器改进 GAN

Improving GANs with A Dynamic Discriminator 公众号&#xff1a;EDPJ 目录 0. 摘要 1. 简介 2. 相关工作 3. 方法 3.1 基础 3.2 动态鉴别器 3.3 针对不同数据体系的两种方案 4. 实验 4.1 设置 4.2 实证研究 4.3 与现有方法的比较 4.4 DynamicD 的泛化性和兼…

如何从底层优化memmove

如何从底层优化memmove 先实现memmove: 如果没有重叠&#xff0c;可以按任何方向拷贝如果有重叠&#xff0c;先拷贝重叠位置&#xff0c;再考虑是前重叠还是后重叠 优化策略&#xff1a; 拷贝数据的时候应该根据寄存器的大小来设计拷贝单位&#xff0c;注意数据区域可能不是…