小白都看懂了,Python 中的线程和进程精讲,建议收藏_python 线程 进程(1)


### 1、 常用方法



Thread.run(self) # 线程启动时运行的方法,由该方法调用 target 参数所指定的函数
Thread.start(self) # 启动线程,start 方法就是去调用 run 方法
Thread.terminate(self) # 强制终止线程
Thread.join(self, timeout) # 阻塞调用,主线程进行等待
Thread.setDaemon(self, daemonic) # 将子线程设置为守护线程
Thread.getName(self, name) # 获取线程名称
Thread.setName(self, name) # 设置线程名称


### 2、 常用参数




| 参数 | 说明 |
| --- | --- |
| target | 表示调用对象,即子线程要执行的任务 |
| name | 子线程的名称 |
| args | 传入 target 函数中的位置参数,是一个元组,参数后必须添加逗号 |


### 3、 多线程的应用


### 3.1 重写线程法



import time, queue, threading

class MyThread(threading.Thread):

def __init__(self):
    super().__init__()
    self.daemon = True  # 开启守护模式
    self.queue = queue.Queue(3)  # 开启队列对象,存储三个任务
    self.start()  # 实例化的时候直接启动线程,不需要手动启动线程

def run(self) -> None:  # run方法线程自带的方法,内置方法,在线程运行时会自动调用
    while True:  # 不断处理任务
        func, args, kwargs = self.queue.get()
        func(*args, **kwargs)  # 调用函数执行任务 元组不定长记得一定要拆包
        self.queue.task_done()  # 解决一个任务就让计数器减一,避免阻塞

# 生产者模型
def submit_tasks(self, func, args=(), kwargs={}):  # func为要执行的任务,加入不定长参数使用(默认使用默认参数)
    self.queue.put((func, args, kwargs))  # 提交任务

# 重写join方法
def join(self) -> None:
    self.queue.join()  # 查看队列计时器是否为0 任务为空 为空关闭队列

def f2(*args, **kwargs):
time.sleep(2)
print(“任务2完成”, args, kwargs)

实例化线程对象

mt = MyThread()

提交任务

mt.submit_tasks(f2, args=(“aa”, “aasd”), kwargs={“a”: 2, “s”: 3})

让主线程等待子线程结束再结束

mt.join()


守护模式:


* 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束


### 3.2 直接调用法



def f2(i):
time.sleep(2)
print(“任务2完成”, i)

lis = []
for i in range(5):
t = Thread(target=f2, args=(i,))
t.start() # 启动 5 个线程
lis.append(t)

for i in lis:
i.join() # 线程等待


### 4、 线程间数据的共享


现在我们程序代码中,有多个线程, 并且在这个几个线程中都会去 操作同一部分内容,那么如何实现这些数据的共享呢?


这时,可以使用 threading库里面的锁对象 Lock 去保护


Lock 对象的acquire方法 是申请锁


每个线程在操作共享数据对象之前,都应该申请获取操作权,也就是调用该共享数据对象对应的锁对象的acquire方法,如果线程A 执行了 acquire() 方法,别的线程B 已经申请到了这个锁, 并且还没有释放,那么 线程A的代码就在此处 等待 线程B 释放锁,不去执行后面的代码。


直到线程B 执行了锁的 release 方法释放了这个锁, 线程A 才可以获取这个锁,就可以执行下面的代码了


如:



import threading

var = 1

添加互斥锁,并且拿到锁

lock = threading.Lock()

定义两个线程要用做的任务

def func1():
global var # 声明全局变量
for i in range(1000000):
lock.acquire() # 操作前上锁
var += i
lock.release() # 操作完后释放锁

def func2():
global var # 声明全局变量
for i in range(1000000):
lock.acquire() # 操作前上锁
var -= i
lock.release() # 操作完后释放锁

创建2个线程

t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func2)
t1.start()
t2.start()
t1.join()
t2.join()
print(var)


到在使用多线程时,如果数据出现和自己预期不符的问题,就可以考虑是否是共享的数据被调用覆盖的问题


使用 threading 库里面的锁对象 Lock 去保护


### 三、 多进程使用


### 1、 简介


Python中的多进程是通过multiprocessing包来实现的,和多线程的threading.Thread差不多,它可以利用multiprocessing.Process对象来创建一个进程对象。这个进程对象的方法和线程对象的方法差不多也有start(), run(), join()等方法,其中有一个方法不同Thread线程对象中的守护线程方法是setDeamon,而Process进程对象的守护进程是通过设置daemon属性来完成的


### 2、 应用


### 2.1 重写进程法



import time
from multiprocessing import Process

class MyProcess(Process): # 继承Process类
def init(self, target, args=(), kwargs={}):
super(MyProcess, self).init()
self.daemon = True # 开启守护进程
self.target = target
self.args = args
self.kwargs = kwargs
self.start() # 自动开启进程

def run(self):
    self.target(*self.args, **self.kwargs)

def fun(*args, **kwargs):
print(time.time())
print(args[0])

if name == ‘main’:
lis = []
for i in range(5):
p = MyProcess(fun, args=(1, ))
lis.append§
for i in lis:
i.join() # 让进程等待


守护模式:


* 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束


### 2.2 直接调用法



import time
from multiprocessing import Process

def fun(*args, **kwargs):
print(time.time())
print(args[0])

if name == ‘main’:
lis = []
for i in range(5):
p = Process(target=fun, args=(1, ))
lis.append§
for i in lis:
i.join() # 让进程等待


### 3、 进程之间的数据共享


### 3.1 Lock 方法


其使用方法和线程的那个 Lock 使用方法类似


### 3.2 Manager 方法


Manager的作用是提供多进程共享的全局变量,Manager()方法会返回一个对象,该对象控制着一个服务进程,该进程中保存的对象运行其他进程使用代理进行操作



Manager支持的类型有:list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和Array


语法:



from multiprocessing import Process, Lock, Manager

def f(n, d, l, lock):
lock.acquire()
d[str(n)] = n
l[n] = -99
lock.release()

if name == ‘main’:
lock = Lock()
with Manager() as manager:
d = manager.dict() # 空字典
l = manager.list(range(10)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 启动10个进程,不同的进程对d和l中的不同元素进行操作
for i in range(10):
p = Process(target=f, args=(i, d, l, lock))
p.start()
p.join()

    print(d)
    print(l)

### 四、 池并发


### 1、 语法


线程池的基类是 concurrent.futures 模块中的 Executor , Executor 提供了两个子类,即 ThreadPoolExecutor 和 ProcessPoolExecutor ,其中 ThreadPoolExecutor 用于创建线程池,而 ProcessPoolExecutor 用于创建进程池


如果使用线程池/进程池来管理并发编程,那么只要将相应的 task 函数提交给线程池/进程池,剩下的事情就由线程池/进程池来搞定


Exectuor 提供了如下常用方法:


* submit(fn, \*args, \* *kwargs):将 fn 函数提交给线程池。* args 代表传给 fn 函数的参数,\*kwargs 代表以关键字参数的形式为 fn 函数传入参数
* map(func, \*iterables, timeout=None, chunksize=1):该函数类似于全局函数 map(func, \*iterables),只是该函数将会启动多个线程,以异步方式立即对 iterables 执行 map 处理。
* shutdown(wait=True):关闭线程池

学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!



### 一、Python所有方向的学习路线



Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。



![](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)



### 二、学习软件

工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。



![](https://img-blog.csdnimg.cn/img_convert/8c4513c1a906b72cbf93031e6781512b.png)



### 三、全套PDF电子书



书籍的好处就在于权威和体系健全,刚开始学习的时候你可以只看视频或者听某个人讲课,但等你学完之后,你觉得你掌握了,这时候建议还是得去看一下书籍,看权威技术书籍也是每个程序员必经之路。

![](https://img-blog.csdnimg.cn/img_convert/46506ae54be168b93cf63939786134ca.png)



### 四、入门学习视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。



![](https://img-blog.csdnimg.cn/afc935d834c5452090670f48eda180e0.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56iL5bqP5aqb56eD56eD,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)



### 五、实战案例



光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。



![](https://img-blog.csdnimg.cn/img_convert/252731a671c1fb70aad5355a2c5eeff0.png)



### 六、面试资料

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。



![](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)  

![](https://img-blog.csdnimg.cn/img_convert/d2d978bb523c810abca3abe69e09bc1a.png)




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里无偿获取](https://bbs.csdn.net/topics/618317507)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值