python - 进程、线程、协程

系统知识

        计算机抽象组成:CPU + 存储器 + IO

        资源:

                1.计算资源:CPU

                2.存储资源:内存、磁盘等

系统知识

        cpu时间片

        对于单核cpu同一时刻只能有一个任务运行

                1.并发:交替执行(某时间段内的处理能力)

                2.并行:同时执行

扫描二维码关注公众号,回复: 14445659 查看本文章

 进程与进程之间的通信方式

        管道

                匿名管道(父子进程之间才能通信)

                命名管道(不是父子进程也能通信)

        信号

                异步通信

                发送信号

                        硬件  ctrl + c

                        

        信号量

        共享内存

        socket

        消息队列

 进程线程

■ 系统知识
• 线程:
线程是操作系统最小的调度单位,
是一串指令的集合
• 进程:
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度
的基本单位

进程与线程

• 真正在cpu上运行的是线程
• 线程共享内存空间;进程的内存是独立的
• 一个线程只能属于一个进程,而一个进程可以有多个线程, 但至少有一个线程
• 资源分配给进程,同一进程的所有线程共享该进程的所有资 源。进程的资源是独立的
• 同一个进程的线程之间可以直接交流;两个进程想通信,必 须通过一个中间代理来实现

 进程 VS 线程

进程  vs  线程

1.一个进程里面是可以有一个以上的线程,这些线程都是可以共享这个内存空间的

2.不同进程之间内存空间都是独立的

3.创建新的线程很简单,创建一个新的进程需要对其父进程进程一次克隆

4.一个线程可以控制和操作同一个进程里的其他线程,进程只能操作子进程

5.一个主线程改变,可能会影响 其他线程,改变父进程不会影响子进程

多任务操作系统工作模式 

多进程模式

多线程模式

多进程 + 多线程模式

一般来说多线程的开销会比多进程少

进程状态模型

进程的三态模型

 进程的五态模型

 Linux五种状态:

        运行、中断,不可中断、僵尸、停止状态

运行 ( 正在运行或在运行队列中等待 )               R
中断 ( 休眠中, 受阻, 在等待某个条件的形成或接受到信号 )     S
不可中断 ( 收到信号不唤醒和不可运行, 进程必须等待直到有中断发生 )     D
僵尸 ( 进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放 )           Z
停止 ( 进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行 )        T

 

使用top命令查看这五种状态 

load average :就绪 + 运行状态 线程队列的一个情况来反映出cpu一段时间内的繁忙程度

例如:1核cpu load average = 1  表示已经处于满负荷的临界点了,load average >  1   就超负荷了。

           2核cpu load average = 2 表示已经处于满负荷的临界点,load average >2就超负荷了。

load average: 0.03, 0.02, 0.05

三个数值,代表1分钟,5分钟,15分钟,表示该时间段内的平均负载

例如:15,5,3  表示最近的时间段负载增长过快

             3,5,15表示最近的时间段负载降低

系统监控命令的数据来源是 /proc目录

/proc  目录在内存的,系统启动以后自动加载

Threading - Thread

threading用于提供线程相关的操作,线程是应用程序中工作的最小单元。

■ Thread构造方法
• 构造方法:
Thread(group=None, target=None, name=None, args=(), kwargs={})
• group: 线程组,目前还没有实现,库引用中提示必须是None;
• target: 要执行的方法;
• name: 线程名;
• args/kwargs: 要传入方法的参数。
■ Thread实例方法
• t.name:获取或设置线程的名称
• t.getName()/setName(name): 获取/设置线程名。
• t.is_alive()、t.isAlive():判断线程是否为激活状态。返回线程是否在运行。正在运行指启动后、终 止前。
• t.ident :获取线程的标识符。线程标识符是一个非零整数,只有在调用了start()方法之后该属性才 有效,否则它只返回None
• t.run() :线程被cpu调度后自动执行线程对象的run方法
• t.start(): 线程准备就绪,等待CPU调度,start会自动调用t.run()
"""
@name : 01.threading模块
@author : wangshenghu
@projectname: tlbb
@Date  : 2022/8/5
"""
import requests
import functools
import time
import threading


def runtime(func):
    # 保留传递进来的函数的元数据,将它的元数据赋值给inner
    @functools.wraps(func)
    def inner(*args, **kwargs):  # 让装饰器更加通用
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"函数执行花了{end -start}s")
        return result
    return inner


def get_content(url):
    text = requests.get(url).content
    time.sleep(0.5)
    print("get content")


@runtime
def main():
    t_list = []
    for i in range(5):
        # get_content("https://www.baidu.com")
        # 创建线程
        # target  -->指定传入的方法的名字 , 要做什么
        # args  --》 指定方法需要传入的参数  元组类型
        # 子线程只做target里面规定的事情
        t = threading.Thread(target=get_content, args=("https://www.baidu.com",))
        t_list.append(t)
        t.start()  # 启动线程  #--》自动执行run方法
    for t in t_list:
        # 阻塞当前环境上下文,知道t的线程执行完成
        # 谁执行这个join代码,谁就是当前环境
        t.join()


main()


执行结果:

E:\python\python3.9.1\python.exe E:/tlbb/2022-08-05-多进程-多线程-协程/01.threading模块.py
get contentget content

get content
get content
get content
函数执行花了0.8148140907287598s

Process finished with exit code 0
• t.join([timeout]): 阻塞当前上下文环境的线程,直到调用此方法的线程终止或到达指定的timeout 可选参数)。
• t.setDaemon(bool): 设置是后台线程(默认前台线程(False))。(在start之前设置)
• 如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,主线程和后台线程均停止
• 如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程 也执行完成后,程序停止
• t.isDaemon:判断是否为后台线程

Threading - Lock

在多线程中使用lock可以让多个线程在共享资源的时候遵循一定的规则。
常见锁类型
• Lock()/RLock:普通锁(互斥锁)
解决资源争用,数据读取不一致等
• Semaphore :信号量
最多允许同时N个线程执行内容
• Event: 事件锁
根据状态位,决定是否通过事件
• Condition: 条件锁

示例:互斥锁

没有添加互斥锁的时候,使用多线程可能会出现资源占用的情况

import threading
import time

num = 0


def sum_num(i):

    global num
    time.sleep(0.5)
    num += i
    print(num)

for i in range(5):
    t = threading.Thread(target=sum_num, args=(i,))
    t.start()

执行结果:

E:\python\python3.9.1\python.exe E:/tlbb/2022-08-05-多进程-多线程-协程/03.互斥锁.py
47
7
910

 示例:添加互斥锁以后

"""
@name : 03.互斥锁
@author : wangshenghu
@projectname: tlbb
@Date  : 2022/8/5
"""
# 互斥锁,
import threading
import time

num = 0


def sum_num(i):
    # 获取锁,同一时间只能有一个线程在这里运行,解决资源占用问题
    lock.acquire()
    global num
    time.sleep(0.5)
    num += i
    print(num)
    # 释放锁
    lock.release()


# 创建一个锁对象
lock = threading.Lock()
for i in range(5):
    t = threading.Thread(target=sum_num, args=(i,))
    t.start()

 执行结果

E:\python\python3.9.1\python.exe E:/tlbb/2022-08-05-多进程-多线程-协程/03.互斥锁.py
0
1
3
6
10

还可以使用with语句来写互斥锁语句

    with lock:
        global num
        time.sleep(0.5)
        num += i
        print(num)

猜你喜欢

转载自blog.csdn.net/qq_48391148/article/details/126172298