博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
12 认识进程与线程 (进阶)
阅读量:5122 次
发布时间:2019-06-13

本文共 3312 字,大约阅读时间需要 11 分钟。

认识进程与线程(python)

  一段时间没有更新博客了,今天和大家讲讲关于 python 进程和线程的知识点。(个人心得,多多指教!)

阶段一:并发与并行的深入理解

​ 并行一定是并发,但并发不一定是并行。

​ 并行是相对的,并行是绝对的。

1、关于并行与并发的问题引入:

问题一: 计算机是如何执行程序指令的?

问题二: 计算机如何模拟出并行执行的效果?

问题三: 真正的并行需要依赖什么?

2、计算机执行指令示意图

2、轮询调度实现并发执行

并发:看上去一起执行,同时在发生

并行:真正一起执行,同时在进行

调度算法:

​ 时间片轮转

​ 优先级调度

3、并行需要的核心条件

​ 并行真正的核心条件是有多个CPU

阶段二:多进程实现并行

1、多进程并行问题引入

问题一: 什么是进程?

问题二: 如何在Python中使用进程?

问题三: 多进程实现并行的必要条件是什么?

2、进程的概念

计算机程序是存储在磁盘上的可执行二进制(或其他类型)文件。

​ 只有把它们加载到内存中,并被操作系统调用它们才会拥有其自己的生命周期。

进程则是表示的一个正在执行的程序。

​ 每个进程都拥有自己的地址空间、内存、数据栈以及其他用于跟踪执行的辅助数据

操作系统负责其上所有进程的执行。

​ 操作系统会为这些进程合理地分配执行时间。

3、在Python中直接执行耗时函数
import time​print('main-task start:', time.asctime(time.localtime(time.time())))​def func():    print('sub-task start:', time.asctime(time.localtime(time.time())))    time.sleep(5)    print('sub-task end:', time.asctime(time.localtime(time.time())))​func()time.sleep(5)print('main-task end:', time.asctime(time.localtime(time.time())))
4、在Python中使用进程来分担耗时任务
import timeimport multiprocessing​def func(n):    for i in range(n):        for a in range(n):            for b in range(n):                print(b)​start_time = time.time()​p = multiprocessing.Process(target=func, args=(50, ))    # 实例化,创建一个进程# 参数如何传?  args=(50, )  kwargs={'n': 50}p.start()   # 开启进程p.join()    # 主进程等待子进程结束​func(50)# func(50)​end_time = time.time()print('运行了%ds!' % (end_time - start_time))
5、多进程并行的必要条件

总进程数量不多于CPU核心数量!

​ 因此,现在运行的程序都是轮询调度产生的并行假象。但是在Python层面的确获得了并行!

阶段三:多线程实现并发

1、多线程并发问题引入

问题一: 什么是线程?

问题二: 如何在Python中使用线程?

问题三: 为什么多线程不是并行?

2、线程的概念

线程被称作轻量级进程。

​ 与进程类似,不过它们是在同一个进程下执行的。并且它们会共享相同的上下文。

当其他线程运行时,它可以被抢占(中断)和临时挂起(也成为睡眠)— 让步

​ 线程的轮询调度机制类似于进程的轮询调度。只不过这个调度不是由操作系统来负责,而是由Python解释器来负责。

3、在Python中使用线程来避开阻塞任务
import timeimport multiprocessingimport threading​print('---outer--start---:', time.asctime(time.localtime(time.time())))​def func():    print('---inner--start---:', time.asctime(time.localtime(time.time())))    time.sleep(5)    print('---inner--end---:', time.asctime(time.localtime(time.time())))​"""在进程里可以模拟耗时任务,但是在线程里只能模拟阻塞任务,不能模拟耗时任务。因为多线程只有一个核心进程。"""p = multiprocessing.Process(target=func)    # 创建子进程t = threading.Thread(target=func)   # 创建子线程t.start()   # 开启子线程​time.sleep(5)print('---outer--end---:', time.asctime(time.localtime(time.time())))

CPU在任意一个进程里,任意时刻,只能执行一个线程

​ 对进程的轮询是操作系统负责调度

​ 对线程的轮询是Python解释器负责调度

4、GIL锁 全局解释器锁

Python在设计的时候,还没有多核处理器的概念。

因此,为了设计方便与线程安全,直接设计了一个锁。

这个锁要求,任何进程中,一次只能有一个线程在执行。

因此,并不能为多个线程分配多个CPU。

所以Python中的线程只能实现并发,

而不能实现真正的并行。

但是Python3中的GIL锁有一个很棒的设计,

在遇到阻塞(不是耗时)的时候,会自动切换线程。

5、GIL锁带给我们的新认知

遇到阻塞就自动切换。因此我们可以利用这种机制来有效的避开阻塞~充分利用CPU

阶段四:使用多进程与多线程来实现并发服务器

关键点一: 多进程是并行执行,

​ 相当于分别独立得处理各个请求。

关键点二: 多线程,虽然不能并行运行,

​ 但是可以通过避开阻塞切换线程

​ 来实现并发的效果,并且不浪费CUP

from socket import *from multiprocessing import Process     # 进程from threading import Thread    # 线程​# 创建套接字server = socket()server.bind(('', 9999))server.listen(1000)​# 定义函数def func(conn):    while True:        recv_data = conn.recv(1024)        if recv_data:            print(recv_data)            conn.send(recv_data)        else:            conn.close()            break​​while True:   # 循环去监听    conn, addr = server.accept()    # 每生成一个对等连接套接字,我就生成一个进程、线程,并且我让这个进程、线程去服务这个连接过来的客户端​    # p = Process(target=func, args=(conn, ))    # 生成一个进程    # p.start()   # 启动进程​​    t = Thread(target=func, args=(conn, ))    # 生成一个线程    t.start()   # 启动线程

转载于:https://www.cnblogs.com/zcmq/p/9886374.html

你可能感兴趣的文章
HTML5新标签在低版本浏览器中兼容性Checklist (hacks and issues)
查看>>
Laravel框架使用的一些注意细节(一)
查看>>
android-------非常好的图片加载框架和缓存库(Picasso)
查看>>
一次Redis 的性能测试和问题 [问题已经自己解决,见文章最后]
查看>>
原型模式(Prototype)
查看>>
Oracle数据库备份与恢复
查看>>
1007: [HNOI2008]水平可见直线
查看>>
网易2017校招编程题
查看>>
mybatis-plus之Mapper CRUD接口和 Service CRUD 接口
查看>>
android sudio 记录
查看>>
《我们仨》读后感
查看>>
100-days: twenty-four
查看>>
javascript定义对象写法
查看>>
pat06-图4. Saving James Bond - Hard Version (30)
查看>>
HDU 1257 最少拦截系统(Dilworth定理+LIS)
查看>>
Redis ConnectionException
查看>>
opencv Mat isContinuous()
查看>>
【noiOJ】p8206
查看>>
iOS:网络请求(17-12-26更)
查看>>
洛谷 P2616 [USACO10JAN]购买饲料II Buying Feed, II
查看>>