Python中多线程、多进程

一、多进程
进程:一个程序,它是一组资源的集合;一个进程里面默认是有一个线程的,这个进程为主线程;多进程是可以利用多核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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值