进程、线程在python中的运用一

本文介绍了操作系统的基础知识,包括物理CPU与逻辑CPU的区别、内核的五大子系统和进程调度策略。深入探讨了内存空间的用户态与内核态,并分析了线程与进程之间的关系及线程的实现。同时,展示了Python的`threading`模块如何创建和管理线程,以及线程间的通信方式如信号、共享内存和消息队列。最后,提供了一个多线程下载的代码示例。
摘要由CSDN通过智能技术生成

一、操作系统知识

计算机的组成:cpu 存储 IO(input、output)
资源:
计算资源:cpu
存储资源:内存、磁盘

1、物理cpu vs 逻辑cpu

真正计算的是逻辑cpu,一个cpu同一时间只能做一间事情

并发:交替执行(某段时间内处理能力)
并行:同时执行
在这里插入图片描述
在这里插入图片描述

2、内核 操作系统的核心代码

Linux操作系统 五大子系统 (cpu 硬盘 内存 网卡等)

Ⅰ、进程调度 :先进先出、短作业优先(谁运行的快谁先来)、优先级
Ⅱ、内存管理 虚拟内存 虚拟地址映射 端也中断 内存的分配管理:伙伴系统(这些自己去了解)
Ⅲ、文件系统 虚拟文件系统 ext系统系统 xfs系统
Ⅳ、网络接口

Ⅴ、进程通信:
1、管道:(形成环道)
----匿名管道(父子进程之间才能通信)
----命名空间(不是父子进程也能通信)
2、信号(内核)、
异步通信
发送信号
{软件(kill)
有些信号是可以拒绝的
信号的本质 修改程序pcb(进程控制块)}
hup信号 —nohup
可以重新加载子进程
重启和重新加载 (重新加载是hup 1号信号 )
3、信号量、(一般搭配共享内存使用)
防止出现“脏数据“
是一种锁 可以规定同一时刻有几个程序可以访问这个共享内存
4、共享内存、 进程a和进程b都以为自己独占内存空间
最快通信方式

查看共享内存

 [root@VM-12-8-centos nginx.service.d]# ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00005feb 0          root       666        12000

5、socket、
一般不同主机上的不同进程通信,也可以用在同一主机不同进程
6、消息队列(支持传输的类型多一点、内核启动就创建好了、储存空间比较小)

3、内存空间:用户空间和内存空间

cpu两种状态:用户态(运行普通程序)、内核态(运行内核程序)
进程通过系统系统调用访问内核空间

[root@VM-12-8-centos ~]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Jul19 ?        00:05:11 /usr/lib/systemd/systemd --system --deser
root         2     0  0 Jul19 ?        00:00:00 [kthreadd]    内核进程
root         4     2  0 Jul19 ?        00:00:00 [kworker/0:0H]
root         6     2  0 Jul19 ?        00:01:10 [ksoftirqd/0]
root      4793     1  0 Jul19 ?        00:00:00 nginx: master process nginx
jay-zhou 26475  4793  0 Jul23 ?        00:00:00 nginx: worker process
jay-zhou 26476  4793  0 Jul23 ?        00:00:00 nginx: worker process

ppid 父进程的进程号。 所有的内核进程都是由kthreadd 2号进程创建,用户的进程由systemd 1号进程创建
父子进程通过匿名管道通信
管道可以说是队列,一个进程往里面写,一个进程往里面读。
所有的进程都是由另外一个进程创建的

四、线程

线程是运行在进程之上的

线程
• 线程被称为轻量级进程(Lightweight Process,LWP),是cpu调度的基本单位
• 组成:线程ID、当前指令指针(PC)、寄存器集合、堆栈组成
• 在单个程序中同时运行多个线程完成不同的工作,称为多线程

1、进程 vs 线程

1、一个进程里可以有一个以上的线程(同一间事多个人处理,提高效率),这些线程都是共享这个内存空间的
2、不同进程之间内存空间都是独立的
3、创建一个新的进程很简单,创建一个新的进程需要对其父进行一次克隆
4、一个进程可以控制同一个进程里的其他线程,进程只能操作子进程
5、一个主线程改变,可能会影响其他线程,改变父进程不会影响子进程

在这里插入图片描述

2、threading模块提供的常用类:

• Thread:创建线程
• Lock/RLock:互斥锁

Thread构造方法
• 构造方法: Thread(group=None, target=None, name=None, args=(), kwargs={})
• group: 线程组,目前还没有实现,库引用中提示必须是None;
• target: 要执行的方法;
• name: 线程名;
• args/kwargs: 要传入方法的参数

3、代码实现

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  --> 指定方法需要传入的参数,  元组类型
        t = threading.Thread(target = get_content, args = ("https://www.baidu.com",))
        t_list.append(t)
        # 默认是前台线程,主线程执行完了,等子线程执行完在推出
        t.setDaemon(True) # 设置后台线程,主线程退出子线程也退出
        t.start() # 启动线程  ---》自动执行run方法

    # 这部分是主线程去做的
    for t in t_list:
        # 阻塞当前环境上下文,知道t的线程执行完成
        # 谁执行这个join代码,谁就是当前环境主线程
        t.join(timeout=3)# 也可以不写timeout,
    print("ending-----------")

main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值