1、python的多线程

  多线程就是在同一时刻执行多个不同的程序,然而python中的多线程并不能真正的实现并行,这是由于cpython解释器中的GIL(全局解释器锁)捣的鬼,这把锁保证了同一时刻只有一个线程被执行。

  多线程的特点:

    线程比进程更轻量级,创建一个线程要比创建一个进程快10-100倍。

    线程共享全局变量。

    由于GIL的原因,当一个线程遇到IO操作时,会切换到另一个线程,所以线程适合IO密集型操作。

    在多核cpu系统中,最大限度的利用多核,可以开启多个线程,开销比进程小的多,但是这并不适合python。

  多线程互斥锁:

    因为线程共享全局变量,所以需要互斥锁去限制线程对全局变量的更改。

    假设,当一个线程在执行到获取全局变量的时候,这个后GIL切换到另一个线程执行,这个时候新的线程为全局变量+1后切换回之前的线程,之前的线程中的全局变量还是+1前的值,所以需要互斥锁。

  为什么有了GIL锁还要互斥锁呢?

    GIL锁只是控制同一时刻下只有一个线程被执行,这并不能控制同一时刻只有一个线程去获取并更改全局变量,所以需要使用互斥锁。

  多线程的实现:

# 导入threading模块
import threading
# 定义全局变量
i=0
# 定义互斥锁
mutex = threading.Lock()
def a():
# 申明全局变量i
global i
for j in range(2000000):
# 获取互斥锁
mutex.acquire()
i+=1
# 释放互斥锁
mutex.release() def b():
global i
for j in range(2000000):
mutex.acquire()
i+=1
mutex.release()
# 创建线程
t1 = threading.Thread(target=a)
t2 = threading.Thread(target=b)
# 开启线程
t1.start()
t2.start()
# 等待所有线程结束
t1.join()
t2.join()
print(i)

2、python中的多进程

  python的多线程不能利用多核的优势,如果想要充分的利用多核cpu的资源,python中大部分情况需要使用多进程。

  python多进程的特点:

    进程间不共享全局变量,进程修改的数据仅限于该进程内。

    进程创建和销毁的开销比较大。

    相对于线程,进程更适合与计算密集型操作。

    能充分利用多核的优势。  

  进程间通信:

    既然进程间中不公共享全局变量,那么多进程间怎么进行通信呢?可以使用multiprocessing中的Queue模块,当然也可以使用socket、管道、共享内存等方式。

  多进程的实现:

# 导入multiprocessin模块
import multiprocessing
# 创建队列
queue = multiprocessing.Queue()
# 定义全局变量
a = 0
# 定义函数
def work1(num):
# 获取队列中的数据,如果没有数据,将堵塞
a = queue.get()
# 将队列中的数据+2000000次num
for i in range(2000000):
a+=num
# 将数据存放在队列中
queue.put(a)
# 打印最终结果
print("work1",a)
# 定义函数
def work2():
# 申明全局变量a
global a
# 将a+2000000次1
for i in range(2000000):
a+=1
# 打印最总结果
print("work2",a)
# 将a存放在队列中
queue.put(a)
# 创建进程
p1 = multiprocessing.Process(target=work1, args=(2,))
p2 = multiprocessing.Process(target=work2)
# 启动进程
p1.start()
p2.start()
# 等待进程结束
p1.join()
p2.join()
# 获取队列中的数据
a = queue.get()
# 打印a
print(a)

  进程池的实现

  进程池能减少重复创建和销毁进程的开销问题

# 导入需要的模块
import multiprocessing
import time
import random
# 定义函数
def work(num):
print("num=",num)
time.sleep(random.randint(0,2))
# 创建进程池,设置进程的数量
pool = multiprocessing.Pool(3)
for i in range(10):
# 开启进程
pool.apply_async(work, args=(i,))
# 设置等待时间,等待所有进程结束
time.sleep(20)

3、python中的协程

  在linux中线程就是轻量级的进程,而我们通常也把协程称为轻量级的线程。

  对比进程和协程:

    进程是内核调度,而协程是在用户态调度,所以说进程的上下文在内核态保存恢复,而协程是在用户态保存恢复的,所以协程的开销比进程低。

    进程会被抢占,而协程不会,也就是说协程如果不主动让出cpu,那么其他的协程就没有执行的机会。

    进程所需要的内存比协程大得多

  对比线程和协程:

    线程的上下文切换成本相对于协程来说比较高。

    线程的切换由操作系统来控制,而协程的切换由我们自己控制。

  yield实现协程:

# 定义两个函数
def work1():
while True:
print("work1")
# 当程序运行到yield就会暂停,等待下次的next调用,然后继续执行
yield
def work2():
while True:
print("work2")
yield w1 = work1()
w2 = work2()
while True:
# 使用next函数启动
next(w1)
next(w2)

  greenlet实现协程:

    greenlet安装:   

sudo pip3 install greenlet

    code:

# 导入greenlet模块
from greenlet import greenlet
def work1():
for i in range(10):
print("work1")
# 打印过后跳转至协程g2继续执行
g2.switch() def work2():
for i in range(10):
print("work2")
# 打印后跳转至协程g1继续执行
g1.switch() # 创建协程g1
g1 = greenlet(work1)
# 创建协程g2
g2 = greenlet(work2)
# 跳转至协程g1
g1.switch()

  gevent实现协程:

    gevent是基于greenlet的并发网络库,每当有一个协程堵塞的时,程序将自动调度。

    monkey-patching:

      一般称为猴子补丁,这个补丁能直接修改标准库里面大部分的阻塞式系统调用。但是如果在复杂的生产环境中使用了这些标准库,可能就会因为打了补丁而出现奇怪的问题。

    gevent安装:

sudo pip3 install gevent

    code:

# 导入所需要的模块
import gevent
import time
from gevent import monkey
# 猴子补丁,monkey.patch_all()方法将所有的标准库都替换掉
# 使用猴子补丁褒贬不一,但是官网上还是建议使用patch_all(),而且在程序的第一行就执行
monkey.patch_all()
def f(n):
for i in range(n):
print(i)
# 设置延时
time.sleep(0.5)
# 如果没有导入monkey模块的话,需要使用gevent.sleep()
# gevent.sleep(0.5) # ----------------写法一--------------------
# 创建greenlet协程对象
# g1 = gevent.spawn(f,5)
# g2 = gevent.spawn(f,5)
# g3 = gevent.spawn(f,5)
# 等待所有greenlet携程结束后退出
# g1.join()
# g2.join()
# g3.join() # ----------------写法二--------------------
gevent.joinall([gevent.spawn(f,5), gevent.spawn(f,5), gevent.spawn(f,5)])

  

  

    

 
 
 

python的进程/线程/协程的更多相关文章

  1. python进阶——进程/线程/协程

    1 python线程 python中Threading模块用于提供线程相关的操作,线程是应用程序中执行的最小单元. #!/usr/bin/env python # -*- coding:utf-8 - ...

  2. Python中进程线程协程小结

    进程与线程的概念 进程 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程.需要强调的是:同一个程序执行两次,那也是两个进程. 进程:资源管理单位(容器). 线程:最小执行单位,管理线程的是进程. ...

  3. Python并发编程系列之常用概念剖析:并行 串行 并发 同步 异步 阻塞 非阻塞 进程 线程 协程

    1 引言 并发.并行.串行.同步.异步.阻塞.非阻塞.进程.线程.协程是并发编程中的常见概念,相似却也有却不尽相同,令人头痛,这一篇博文中我们来区分一下这些概念. 2 并发与并行 在解释并发与并行之前 ...

  4. Python 进程线程协程 GIL 闭包 与高阶函数(五)

    Python 进程线程协程 GIL 闭包 与高阶函数(五) 1 GIL线程全局锁 ​ 线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的 ...

  5. python自动化开发学习 进程, 线程, 协程

    python自动化开发学习 进程, 线程, 协程   前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...

  6. 进程&线程&协程

    进程  一.基本概念 进程是系统资源分配的最小单位, 程序隔离的边界系统由一个个进程(程序)组成.一般情况下,包括文本区域(text region).数据区域(data region)和堆栈(stac ...

  7. 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型

    本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...

  8. python进程/线程/协程

    一 背景知识 顾名思义,进程即正在执行的一个过程.进程是对正在运行程序的一个抽象. 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所 ...

  9. python-socket和进程线程协程(代码展示)

    socket # 一.socket # TCP服务端 import socket # 导入socket tcp_sk = socket.socket() # 实例化一个服务器对象 tcp_sk.bin ...

随机推荐

  1. 洛谷P2050 美食节

    修车加强版.发现每个厨师拆成p个点太浪费了,毕竟总共用到的才p个点.于是从下往上一个一个加,加到满流就停. 论动态加点费用流的正确姿势...... 我自己加总是出现负环...我是每次加一整层,然后跑完 ...

  2. 跟我一起使用android Studio打包react-native项目的APK

    使用的是react-native的hello-world项目 第一步:创建项目 npm install -g yarn react-native-cli react-native init Aweso ...

  3. (链表) leetcode 328. Odd Even Linked List

    Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...

  4. Qt ------ window下工程项目打包成一个exe程序

    最近,在学习QT5的过程中,想尝试着把自己写的工程程序给打包发布出来,在任何一台windows系统都能运行,这样就不会限于电脑需不需要安装QT安装包了. 首先,先介绍自己使用的环境.我使用的QT版本是 ...

  5. 字节输入流 FileInputStream

    字节输入流 InputStream : 方法介绍: read(); 读取下一个字节 返回-1读取文件结束 close(); 复制文件 将数据aaa.txt复制到d盘 字节输入流读---->字节输 ...

  6. 字节输出流 FileOutputStream

    输入和输出 : 参照物 都是java程序来参照 output 内存---->硬盘 input 持久化数据-->内存 字节流输出 定义:流按照方向可以分为输入和输出流 字节流 :可以操作任何 ...

  7. linux文件或目录权限修改后如何恢复(备份了权限就能恢复)

    操作系统 RHEL5 如果你在linux上执行了如下操作chmod -R 777 / 或者 chmod -R 700 /那么恭喜你,你的系统即将崩溃,重启之后,你进不了图形界面,而且很多服务都起不来 ...

  8. kubeadm安装Kubernetes V1.10集群详细文档

    https://www.kubernetes.org.cn/3808.html?tdsourcetag=s_pcqq_aiomsg 1:服务器信息以及节点介绍 系统信息:centos1708 mini ...

  9. jmeter5.0 while controller使用总结

    while controller 配合sql使用的方式 在while控制器条件中填空,这样当里面的请求断言失败后就会跳出循环 在while控制器条件中填LAST,当里面的请求断言失败后就会跳出循环,如 ...

  10. 编写Excel文件的Golang库

    github:https://github.com/360EntSecGroup-Skylar/excelize 使用用例 https://dev.to/xuri/go-library-for-rea ...