python多线程与多进程

一:为什么

进程(process)和线程(thread)是非常抽象的两个概念,但也是一位python程序员必不可少的技能。尤其在进行cpu大数据计算时,就是一个非常好的加速方式。

 

二:基础知识

1.线程:线程是一个基本的CPU执行单元,它可以和统一进程下的其他线程共享全部资源。

2.进程:进程是指一个程序在给定数据集合上的一次执行过程,是系统进行资源分配和运行调用的独立单位。每个进程都有自己的地址空间。也就是说一个应用程序至少包括1个进程,而1个进程包括1个或多个线程。

3.线程的类型:

线程按照作用可大致划分为:

主线程

子线程

后台线程

前台线程

 

三:python多线程

注意:现在的cpu都是多核cpu,是支持多个线程同时执行的,但是python同时只能有一个线程在执行。

其主要原因是GIL的存在,每次释放 GIL锁,线程进行锁竞争、切换线程,会消耗资源。这就导致打印线程执行时长,会发现耗时更长的原因。

 

1.创建多线程

Python提供了threading模块。

thread.Thread()函数需要接受两个参数,第一个是target,一般指要调用的函数名,第二个args,表示需要向函数中传递的参数。
start()开启多线程。
threading.current_thread().name打印出当前线程的名字。
threading.enumerate()
返回一个包含正在运行的线程的list
import threading

def test1():
    print(threading.current_thread().name)

def test2():
    print(threading.current_thread().name)

print(threading.current_thread().name)#可以打印出当前线程的名字
print(threading.enumerate())#返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
thread1 = threading.Thread(target=test1,name="thread1")
thread2 = threading.Thread(target=test2,name="thread2")
thread1.start()
thread2.start()#把线程开起来

结果

 

 

2.线程等待

当我们子线程还在运行时,但是主线程已经在往下运行。主线程结束后,子线程还在运行,join函数使得主线程等到子线程结束后再往下运行。

import time
import threading

def test1():
    print(threading.current_thread().name)
    time.sleep(2)
    print("thread1end")
def test2():
    print(threading.current_thread().name)
    time.sleep(5)
    print("thread2end")


print(threading.current_thread().name)#可以打印出当前线程的名字
print(threading.enumerate())#返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
thread1 = threading.Thread(target=test1,name="thread1")
thread2 = threading.Thread(target=test2,name="thread2")
thread1.start()
thread2.start()#把线程开起来
print("*********")

结果:

加入等待join()

import time
import threading

def test1():
    print(threading.current_thread().name)
    time.sleep(2)
    print("thread1end")
def test2():
    print(threading.current_thread().name)
    time.sleep(5)
    print("thread2end")


print(threading.current_thread().name)#可以打印出当前线程的名字
print(threading.enumerate())#返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
thread1 = threading.Thread(target=test1,name="thread1")
thread2 = threading.Thread(target=test2,name="thread2")
thread1.start()
thread2.start()#把线程开起来
thread2.join()
thread1.join()#等上面的线程都运行完了,再运行下面的代码
print("*********")

结果:

3.数据传输

利用Queue实现不同线程间的沟通,它主要有两个函数,put和get。put() 用以插入数据到队列中,get()可以从队列读取并且删除一个元素。

import time
import threading
from queue import Queue

def test1(q):
    print(threading.current_thread().name)
    time.sleep(2)
    print("thread1end")
    q.put([1,2,3])
def test2(q):
    print(threading.current_thread().name)
    time.sleep(5)
    print("thread2end")
    q.put([4,5,6])


print(threading.current_thread().name)#可以打印出当前线程的名字
print(threading.enumerate())#返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
qq=Queue()

thread1 = threading.Thread(target=test1,name="thread1",args=(qq,))
thread2 = threading.Thread(target=test2,name="thread2",args=(qq,))
thread1.start()
thread2.start()#把线程开起来
thread2.join()
thread1.join()#等上面的线程都运行完了,再运行下面的代码
print("*********")
print(qq.get())
print(qq.get())

结果:

四:python多进程

利用multiprocess模块创建多进程,其中有两种创建方式。

1.方式一

利用Pool类,Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果进程池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。

Pool常用方法如下:

apply()同步执行(串行)
apply_aspnc()异步执行(并行)
terminate()立刻关闭进程池
join()主进程等待所有子进程执行完毕
close()等待所有进程结束后,才关闭进程池
import multiprocessing
import time
def test1(q,):
    print("test1")
    q.put(1)
def test2(q,):
    time.sleep(0.5)
    print("test2")
    q.put(2)
if __name__=="__main__":
    q=multiprocessing.Queue()
    q2=multiprocessing.Queue()
    pool=multiprocessing.Pool(3)
    pool.apply_async(test1,args=(q,))
    pool.apply_async(test1,args=(q2,))
    pool.close()#join之前要调用close
    pool.join()

2.方式二

直接使用Process实现多进程,其中也要利用Queue来完成各进程的沟通。

import multiprocessing
import time
def test1(q):
    print("test1")
    q.put([1,2,3])
def test2(q,):
    time.sleep(0.5)
    print("test2")
    q.put([2])
if __name__ == '__main__':
    qq=multiprocessing.Queue()
    qq2=multiprocessing.Queue()
    pro=multiprocessing.Process(target=test1,args=(qq,))
    pro2 = multiprocessing.Process(target=test2, args=(qq2,))
    pro.start()
    pro2.start()
    pro2.join()
    pro.join()
    print(qq.get())
    print(qq2.get())

结果:

五:总结(多线程与多进程选择?)

本文总结了python的多线程与多进程的区别,并且详细介绍了threading与multiprocess模块进行多线程和多进程的编程。

对于CPU密集型代码(如循环)-使用多进程

对于IO密集型代码(如文件操作,网络爬虫)-多线程效率更高。

 

六:参考:

https://www.huaweicloud.com/articles/8c1da1adad72034695b4e40fe7501063.html

https://www.jianshu.com/p/a69dec87e646

公众号:柯西的笔,欢迎大家关注,时不时更新深度学习,机器学习,医学算法。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯西的笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值