Python 多线程
1 # 线程 2 # 1.Thread 3 import threading 4 def func(a,b): 5 pass 6 t1 = threading.Thread(target=func, args=(1,2,)) 7 t1.start() 8 # 2.继承 9 class MyThread(threading.Thread): 10 def run(self, a,b): 11 pass 12 t1 = MyThread(args=(1,2,)) 13 t1.start() 14 # 进程 15 import multiprocess 16 def func(a,b): 17 pass 18 t1 = multiprocess.Process(target=func, args=(1,2,)) 19 t1.start() 20 21 # 进程和线程区别: 22 # 1.进程是包含线程,也就是线程是在进程中创建了,一个进程可以创建多个线程。进程在创建的时候会默认创建一个进程,该进程称之为主线程,我们的代码都是由主线程开始的,所以我们在主线程中创建的线程都称之为子线程。 23 # 2.CPU调度是以进程为单位的,每个进程都是有GIL锁存在的。GIL锁的功能是保证CPU调度同一时刻只有一个现在被CPU调用。 24 # 3.因为GIL的存在掉,所以并行处理我们到底应该采用多线程还是多进程,它的标准就是你的程序需要CPU计算的强度来决定。如果你的程序是用来公式计算、数据分析就选多进程,如果你的程序偏I/O或者网络传输你就选线程,或者多进程和多线程配合使用。 25 26 # 线程方法 27 t1.join() # 主线程创建并t1.start()后,主线程调用t1.join()后就会阻塞等待t1线程执行完 28 t1.setDeamon(False) # 主线程中调用,是否等待子线程执行完。和t1.join()一个意思,区别是:setDeamon必须在start之前执行,并且是在主线程结束的时候去检查子线程是否结束 29 t1.setName(str) # 设置线程的名字,也是在start前设置 30 threading.current_thread().getName() # 获取当前线程的名字 31 32 # 线程锁 33 import threading 34 lock_obj = threading.RLock() # threading.Lock() 他们的区别是RLock嵌套锁 35 data = [1,2,3,4] 36 def func(a,b): 37 lock_obj.acquire() # 申请锁,没申请到就等待 38 lock_obj.acquire() # RLock嵌套锁才可以重复申请锁 39 data # 中间访问的数据就是被锁住的数据 40 lock_obj.release() 41 lock_obj.release() # 释放锁,别的线程才可以使用 42 t1 = threading.Thread(target=func, args=(1,2,)) 43 t1.start() 44 # 线程安全:在python中一些数据类型里有些函数是自动带有线程锁的,比如: 45 list.append(x) 46 list.extend(1,2) 47 x = list[i] 48 list.sort() 49 x = y 50 x.field = y 51 dict[key] = xx 52 dict.update(d1) 53 dict.keys() 54 55 # 线程池: 56 # 线程多到一定程度并不会提高工作效率,反而会有影响 57 # 线程池就是用来限制同一时间最多有多少个线程在运行 58 # 如果你的线程池子设置最多同时执行10个线程,而往线程池中推送一百个任务的话,那么线程池子就会排队去执行它,保证同一时间最多只有10个线程运行 59 import time 60 import random 61 from concurrent.futures import ThreadPoolExecutor, Future 62 63 def task(video_url, t): 64 print('线程开始:', video_url) 65 time.sleep(2) 66 return random.randint(1, 10) 67 def done(response): 68 print('任务执行结果', response.result()) 69 def save(filename): 70 def savefile(response): 71 print('闭包的方式将函数名传过来了', filename) 72 return savefile 73 pool = ThreadPoolExecutor(10) # 创建线程池,最多同时开启10个线程 74 url_list = ['www.xxxx-().com'.format(i) for i in range(15)] 75 for url in url_list: 76 future = pool.submit(task, url, 'filename') # 提交一个任务,第一个参数就是任务的函数名,后面跟的是函数的参数 77 future.add_done_callback(done) # 当任务执行完了之后,会将执行结果当做参数船给done函数执行 78 # future.add_done_callback(save('filename')) 也可以利用闭包的方式将文件名参数提前传到函数中去 79 pool.shutdown(True) # 相当于线程中的join 80 81 # 多线程单例模式 82 import threading 83 import time 84 85 class Singleton(threading.Thread): 86 instance = None 87 lock = threading.RLock() 88 89 def __init__(self, name): 90 threading.Thread.__init__(self) 91 self.name = name 92 def __new__(cls, *args, **kwargs): 93 if cls.instance: 94 return cls.instance 95 with cls.lock: # 自动枷锁解锁。如果不枷锁的话,当多个线程同时创建单例的时候很有可能会创建多个 96 if cls.instance: 97 return cls.instance 98 cls.instance = object.__new__(cls) 99 time.sleep(0.1) 100 return cls.instance
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?