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
复制代码

 

posted @   看一百次夜空里的深蓝  阅读(158)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示