python
并行必定是并发,但并发不必定是并行。算法
并行是相对的,并行是绝对的。安全
问题一: 计算机是如何执行程序指令的?服务器
问题二: 计算机如何模拟出并行执行的效果?多线程
问题三: 真正的并行须要依赖什么?并发
二、计算机执行指令示意图socket
并发:看上去一块儿执行,同时在发生函数
并行:真正一块儿执行,同时在进行spa
调度算法:操作系统
时间片轮转
优先级调度
并行真正的核心条件是有多个CPU
问题一: 什么是进程?
问题二: 如何在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())))
import time import 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))
总进程数量很少于CPU核心数量!
所以,如今运行的程序都是轮询调度产生的并行假象。可是在Python层面的确得到了并行!
问题一: 什么是线程?
问题二: 如何在Python中使用线程?
问题三: 为何多线程不是并行?
线程被称做轻量级进程。
与进程相似,不过它们是在同一个进程下执行的。而且它们会共享相同的上下文。
当其余线程运行时,它能够被抢占(中断)和临时挂起(也成为睡眠)— 让步
线程的轮询调度机制相似于进程的轮询调度。只不过这个调度不是由操做系统来负责,而是由Python解释器来负责。
import time import multiprocessing import 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解释器负责调度
Python在设计的时候,尚未多核处理器的概念。
所以,为了设计方便与线程安全,直接设计了一个锁。
这个锁要求,任何进程中,一次只能有一个线程在执行。
所以,并不能为多个线程分配多个CPU。
因此Python中的线程只能实现并发,
而不能实现真正的并行。
可是Python3中的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() # 启动线程