2024年最新老年人都看懂了,Python 中的线程和进程精讲,已经收藏

众所周知,CPU是计算机的核心,它承担了所有的计算任务。而操作系统是计算机的管理者,是一个大管家,它负责任务的调度,资源的分配和管理,统领整个计算机硬件。应用程序是具有某种功能的程序,程序运行与操作系统之上

2、 线程

=====

在很早的时候计算机并没有线程这个概念,但是随着时代的发展,只用进程来处理程序出现很多的不足。如当一个进程堵塞时,整个程序会停止在堵塞处,并且如果频繁的切换进程,会浪费系统资源。所以线程出现了

线程是能拥有资源和独立运行的最小单位,也是程序执行的最小单位。一个进程可以拥有多个线程,而且属于同一个进程的多个线程间会共享该进行的资源

干货主要有:

======

① 200 多本 Python 电子书(和经典的书籍)应该有

② Python标准库资料(最全中文版)

③ 项目源码(四五十个有趣且可靠的练手项目及源码)

④ Python基础入门、爬虫、网络开发、大数据分析方面的视频(适合小白学习)

⑤ Python学习路线图(告别不入流的学习)

Python学习交流Q群101677771

3、 进程

=====

进程时一个具有一定功能的程序在一个数据集上的一次动态执行过程。进程由程序,数据集合和进程控制块三部分组成。程序用于描述进程要完成的功能,是控制进程执行的指令集;数据集合是程序在执行时需要的数据和工作区;程序控制块(PCB)包含程序的描述信息和控制信息,是进程存在的唯一标志

4、 区别

=====

  1. 一个进程由一个或者多个线程组成,线程是一个进程中代码的不同执行路线

  2. 切换进程需要的资源比切换线程的要多的多

  3. 进程之间相互独立,而同一个进程下的线程共享程序的内存空间(如代码段,数据集,堆栈等)。某进程内的线程在其他进程不可见。换言之,线程共享同一片内存空间,而进程各有独立的内存空间

5、 使用

=====

在Python中,通过两个标准库 thread 和 Threading 提供对线程的支持, threading 对 thread 进行了封装。 threading 模块中提供了 Thread , Lock , RLOCK , Condition 等组件

二、 多线程使用

========

在Python中线程和进程的使用就是通过 Thread 这个类。这个类在我们的 thread 和 threading 模块中。我们一般通过 threading 导入

默认情况下,只要在解释器中,如果没有报错,则说明线程可用

from threading import Thread

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])

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

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

img
img

二、Python必备开发工具

工具都帮大家整理好了,安装就可直接上手!img

三、最新Python学习笔记

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。

img

四、Python视频合集

观看全面零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

img

五、实战案例

纸上得来终觉浅,要学会跟着视频一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。img

六、面试宝典

在这里插入图片描述

在这里插入图片描述

简历模板在这里插入图片描述

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

需要这份系统化学习资料的朋友,可以戳这里无偿获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 14
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值