Python中多线程、多进程

it2023-11-11  74

一、多进程 进程:一个程序,它是一组资源的集合;一个进程里面默认是有一个线程的,这个进程为主线程;多进程是可以利用多核cpu的。

def make_money(): print('开始挣钱') time.sleep(10) def start_process(): for i in range(5): p = multiprocessing.Process(target=make_money) p.start() print(multiprocessing.active_children())#获取当前的进程数 while len(multiprocessing.active_children()) !=1: pass print('运行结束') if __name__ == '__main__': start_process()

二、多线程 线程:是最小的执行单位;线程和线程之间是互相独立的;主线程等待子线程执行结束;线程和线程之间,数据是共享的。 python中有两种方式实现线程,两种方式本质上都是直接或者间接使用threading.Thread类: 1、实例化一个threading.Thread的对象,并传入一个初始化函数对象(initial function )作为线程执行的入口; 2、继承threading.Thread,并重写run函数; 单线程的方式:

def clean(): print('打扫卫生') time.sleep(2) def xiyifu(): print('洗衣服') time.sleep(3) def cook(): print('做饭') time.sleep(1) clean() xiyifu() cook()

多线程方式: 方式1:创建threading.Thread对象

def clean(): print('打扫卫生') time.sleep(2) def xiyifu(): print('洗衣服') time.sleep(3) def cook(): print('做饭') time.sleep(1) t = threading.Thread(target=clean) #子线程 t2 = threading.Thread(target=xiyifu) t3 = threading.Thread(target=cook) t.start() t2.start() t3.start() t.join() t2.join() t3.join()

方式2:继承threading.Thread,并重写run

class mop_floor(threading.Thread): def __init__(self): super().__init__() def run(self): print('打扫卫生') time.sleep(2) class heat_up_watrt(threading.Thread): def __init__(self,name): # 这里传入参数name,就是传入子线程名字 super().__init__(name=name) # 这里的格式不能错 def run(self): print('烧水') print(self.name) print(threading.current_thread().name) # 这两个都是打印出当前子线程的名字 time.sleep(6) start_time = time.time() t1 = mop_floor() t2 = heat_up_watrt('烧水') t1.start() t2.start() t1.join() t2.join()

threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法: threading.currentThread(): 返回当前的线程变量。 threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 threading.activeCount(): 返回正在运行的线程数量,与 len(threading.enumerate())有相同的结果。 除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法: run(): 用以表示线程活动的方法。 start():启动线程活动。 join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。 isAlive(): 返回线程是否活动的。 getName(): 返回线程名。 setName(): 设置线程名。

三、全局解释器锁:GIL锁(Global Interpreter Lock) 这是Python中为了保证数据安全所实现的一种锁。无论进程中有多少线程,只有拿到了GIL锁的线程才可以在CPU上运行,即多核处理器。对一个进程而言,不管有多少线程,任一时刻,只会有一个线程在执行。对于CPU密集型的线程,其效率不仅仅不高,反而有可能比较低。python多线程比较适用于IO密集型的程序。对于的确需要并行运行的程序,可以考虑多进程。 四、守护线程 守护线程就是只要主线程执行完成,不管子线程有没有执行完成,全部都结束。

def talk(name): print('正在和%s聊天'%name) time.sleep(random.randint(1,5)) print('和%s聊完了'%name) t = threading.Thread(target=talk,args=['小红']) t.setDaemon(True) #设成守护线程 t.start() t = threading.Thread(target=talk,args=['小黑']) t.setDaemon(True) #设成守护线程 t.start() t = threading.Thread(target=talk,args=['小明']) t.setDaemon(True) #设成守护线程 t.start() t = threading.Thread(target=talk,args=['小兰']) t.setDaemon(True) #设成守护线程 t.start() print('退出qq')

五、线程锁 线程锁,表示某一单元或空间只为某一线程所有,此时其他线程均无法进行操作,等待该线程操作完成并释放锁之后,其他线程才可继续利用该单元。 实现线程锁: 1、实例化一个锁对象; lock = threading.Lock() 2、操作变量之前进行加锁 lock.acquire() 3、 操作变量之后进行解锁 lock.release()

import threading count = 0 lock = threading.Lock() def add(): global count print(threading.current_thread(),'开始运行') for i in range(1000000): lock.acquire() count+=1 lock.release() for i in range(2): t = threading.Thread(target=add) t.start() while threading.active_count()!=1: pass print(count)

六、线程池 对于任务数量不断增加的程序,每有一个任务就生成一个线程,最终会导致线程数量的失控。所以,对于任务数量不端增加的程序,固定线程数量的线程池是必要的。 七、队列 作用: 异步处理;保证顺序。 Queue模块常用方法: Queue.qsize() 返回队列的大小 Queue.empty() 如果队列为空,返回True,反之False Queue.full() 如果队列满了,返回True,反之False Queue.full 与 maxsize 大小对应 Queue.get([block[, timeout]])获取队列,timeout等待时间 Queue.get_nowait() 相当Queue.get(False) Queue.put(item) 写入队列,timeout等待时间 Queue.put_nowait(item) 相当Queue.put(item, False) Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号 Queue.join() 实际上意味着等到队列为空,再执行别的操作

import queue import random import time import threading orders_q = queue.Queue() #生产者/消费者模式 def producer(): for i in range(100): order_id = random.randint(1, 99999) print('订单生成,orderid:%s'%order_id) orders_q.put(order_id) time.sleep(1) def consumer(): while True: if orders_q.qsize()>0: oreder_id = orders_q.get() print('consumer1,订单落库',oreder_id) def consumer2(): while True: if orders_q.qsize()>0: oreder_id = orders_q.get() print('consumer2,订单落库',oreder_id) t = threading.Thread(target=producer) t.start() t = threading.Thread(target=consumer) t.start() t = threading.Thread(target=consumer2) t.start()
最新回复(0)