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

问题二: 计算机如何实现并发的?

轮询调度实现并发执行 程序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

声明:本文为博主学习感悟总结,水平有限,如果不当,欢迎指正。如果您认为还不错,欢迎转载。转载与引用请注明作者及出处。

python_并行与并发、多线程的更多相关文章

  1. c++11并行、并发与多线程编程

    首先,我们先理解并发和并行的区别. 你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行. 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并 ...

  2. C#并行编程-并发集合

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  3. Java 并行与并发

    Java 并行与并发 注意两个词:并行(Concurrent) 并发(Parallel) 并行:是逻辑上同时发生,指在某一个时间内同时运行多个程序 并发:是物理上同时发生,指在某一个时间点同时运行多个 ...

  4. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程 并行与并发 同步与异步 阻塞与非阻塞 CPU密集型与IO密集型 线程与进程 进 ...

  5. Clojure的并行与并发

    这次来聊聊clojure的并行与并发,如果你还不知clojure为何物,请翻翻我的上一篇推文.“并行”是指clojure对并行计算的支持(parallel computing),“并发”是其并发特性( ...

  6. java并发多线程显式锁Condition条件简介分析与监视器 多线程下篇(四)

    Lock接口提供了方法Condition newCondition();用于获取对应锁的条件,可以在这个条件对象上调用监视器方法 可以理解为,原本借助于synchronized关键字以及锁对象,配备了 ...

  7. java 并发多线程 锁的分类概念介绍 多线程下篇(二)

    接下来对锁的概念再次进行深入的介绍 之前反复的提到锁,通常的理解就是,锁---互斥---同步---阻塞 其实这是常用的独占锁(排它锁)的概念,也是一种简单粗暴的解决方案 抗战电影中,经常出现为了阻止日 ...

  8. java 并发多线程显式锁概念简介 什么是显式锁 多线程下篇(一)

    目前对于同步,仅仅介绍了一个关键字synchronized,可以用于保证线程同步的原子性.可见性.有序性 对于synchronized关键字,对于静态方法默认是以该类的class对象作为锁,对于实例方 ...

  9. 《Go语言实战》摘录:6.1 并发 - 并行 与 并发

    6.1 并行 与 并发

随机推荐

  1. yarn和npm的对比,以及项目中使用方式

    相比npm 的优点 1.npm安装是串行,而yarn是并行,速度大大提升 2.已经下载过的包会被缓存,无需重复下载,更关键的是,支持离线安装 3.精准的版本控制,加上验证每个包的完整性,保证每次安装的 ...

  2. K8s的存储卷使用总结

    K8s的存储卷: 它有四种存储卷: 1. emptyDir: 空目录,这种存储卷会随着Pod的删除而被清空,它一般作为缓存目录使用,或临时目录, 当做缓存目录时,通常会将一块内存空间映射到该目录上,让 ...

  3. K8s configMap原理介绍

    给容器内应用程序传递参数的实现方式: 1. 将配置文件直接打包到镜像中,但这种方式不推荐使用,因为修改配置不够灵活. 2. 通过定义Pod清单时,指定自定义命令行参数,即设定 args:[" ...

  4. FPGA综合的约束

    近日发现,有些逻辑电路的综合时间约束和布局布线约束相差太大时,难以布通.此时,应该选择尽量接近的时钟约束.

  5. gitlab 从古老的 bitnami 版本 迁移到官方最新版本

    这是我之前发布在 yuque 的文章.是我刚来新公司的时候帮公司搬迁 git 记录下来的,现在看来去掉敏感部分直接发布也没啥问题啦,就搬家过来,我自己也方便查 XD . 8.1.6 -> 10. ...

  6. Dice Similarity Coefficent vs. IoU Dice系数和IoU

    Dice Similarity Coefficent vs. IoU Several readers emailed regarding the segmentation performance of ...

  7. hosts 屏蔽广告 定位

    hosts 屏蔽广告 定位 JS Miner 挖矿 百度全家桶的全天候定位记录 各类统计服务(仅屏蔽 JS.不屏蔽控制台) 常见下载劫持 360 和百度的部分软件下载 CNNIC 根证书劫持 http ...

  8. iptables 端口转发--内网实现上网

    iptables -t nat -I POSTROUTING -s 192.168.0.0/24 -j SNAT --to-source 118.x.x.xiptables -A FORWARD -s ...

  9. mybatis在sql中的CDATA区

    示例 <if test="startTime != null"> <![CDATA[ AND rra.create_time >= #{startTime} ...

  10. js使浏览器窗口最大化(适用于IE的方法)

    这里使用的方法是IE的私有特性,只能在IE中有效.主要是window.moveTo和 window.resizeTo方法.       效果和点击最大化按钮差不多,有一点区别.点击最大化按钮后,浏览器 ...