问题一: 计算机是如何执行程序指令的?
问题二: 计算机如何实现并发的?
轮询调度实现并发执行 程序1-8轮询完成,才再CPU上运行
问题三: 真正的并行需要依赖什么?
并行需要的核心条件
多进程实现并行
问题一: 什么是进程?
计算机程序是存储在磁盘上的文件。
只有把它们加载到内存中,并被操作系统调用 它们才会拥有其自己的生命周期。
进程表示一个正在执行的程序。
每个进程都有独立地址空间以及其他的辅助数据
进程(Process)
是计算机中已运行程序的实例
问题二: 如何在Python中使用进程?
import multiprocessing # 导入进程模块 import datetime import time def func(data): while True: print(datetime.datetime.now()) sum = data + 100 print(sum) time.sleep(2) print(datetime.datetime.now()) if __name__ == '__main__': p = multiprocessing.Process(target=func, args=(123,)) # 创建一个进程,args传参 必须是元组 p.start() # 运行线程p while True: time.sleep(2) print("我是主进程")
进程使用步骤
问题三: 多进程实现并行的必要条件是什么?
总进程数量不多于 CPU核心数量!
如果不满足,那么运行的程序都是 轮询调度产生的假象。
多线程实现并发
问题一:什么是线程?
线程被称作轻量级进程。
线程是进程中的一个实体,操作系统不会为进程分配内存空间,它只有一点在运行中必不可少的资源
线程被包含在进程中,是进程中的实际运作单位
同一个进程内的多个线程会共享相同的上下文,
也就是共享资源(内存和数据)。
线程(thread)
是操作系统能够进行运算调度的最小单位
问题二: 如何在Python中使用线程?
import multiprocessing # 引用进程模块 import threading # 引用线程模块 import time def func(data): while True: time.sleep(1) data += 1 print(data) # mult = multiprocessing.Process(target=func, args=(1314,)) # mult.start() # 运行进程 thre = threading.Thread(target=func, args=(500,)) # 创建一个线程 thre.start() # 运行线程 print("这是主进程")
进程使用步骤
问题三: 为什么多线程不是并行?
稳定性
进程具有独立的地址空间,一个进程崩溃后,不会对其它进程产生影响。
线程共享地址空间,一个线程非法操作共享数据崩溃后,整个进程就崩溃了。
创建开销
创建进程操作系统是要分配内存空间和一些其他资源的。开销很大
创建线程操作系统不需要再单独分配资源,开销较小
切换开销
不同进程直接是独立的, 切换需要耗费较大资源
线程共享进程地址空间, 切换开销小
GIL锁(线程锁)
Python在设计的时候,还没有多核处理器的概念。
因此,为了设计方便与线程安全,直接设计了一个锁。
这个锁要求,任何进程中,一次只能有一个线程在执行。
因此,并不能为多个线程分配多个CPU。
所以Python中的线程只能实现并发,
而不能实现真正的并行。
但是Python3中的GIL锁有一个很棒的设计,
在遇到阻塞(不是耗时)的时候,会自动切换线程。
很多库是基于GIL锁写的,取消代价太大
进程可以实现并行和并发
线程只能实现并发
遇到阻塞就自动切换。
我们可以利用这种机制来
充分利用CPU
那么最后:
使用多进程与多线程来实现并发服务器
使用多进程与多线程实现并发服务器的关键点
关键点一: 多进程是并行执行,
相当于分别独立得处理各个请求。
关键点二: 多线程,虽然不能并行运行,
但是可以通过避开阻塞切换线程
来实现并发的效果,并且不浪费cpu
服务端实现代码:
import threading # 创建一个线程 import socket server = socket.socket() server.bind(('0.0.0.0', 8888)) server.listen() # 监听 def workon(conn): while True: data = conn.recv(1024) if data == b'': conn.close() break else: print("接收到的消息: {}".format(data.decode())) conn.send(data) # 主线程 while True: conn, addr = server.accept() print("{}正在连接".format(addr)) # 线程去处理消息 p = threading.Thread(target=workon, args=(conn,)) p.start()
客户端代码:
import socket click = socket.socket() click.connect(('127.0.0.1', 8888)) while True: data = input("请输入你要发送的数据:") click.send(data.encode()) print("接收到的消息: {}".format(click.recv(1024).decode()))
总结完成!
作者:含笑半步颠√
博客链接:https://www.cnblogs.com/lixy-88428977
声明:本文为博主学习感悟总结,水平有限,如果不当,欢迎指正。如果您认为还不错,欢迎转载。转载与引用请注明作者及出处。