c语言多线程转python多线程,真正的python 多线程!一个修饰符让你的多线程和C语言一样快...
> Python 多线程因为GIL的存在,导致其速度比单线程还要慢。但是近期我发现了一个相当好用的库,这个库只需要增加一个修饰符就可以使原生的python多线程实现真正意义上的并发。本文将和大家一起回顾下GIL对于多线程的影响,以及了解通过一个修饰符就可以实现和C++一样的多线程。
## GIL的定义
GIL的全称是global interpreter lock,官方的定义如下:
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.)
从官方的解释来看,这个全局锁是用来防止多线程同时执行底层计算代码的。之所以这么做,是因为底层库Cpython,在内存管理这块是线程不安全的。
## GIL有好处吗
对GIL的第一印象是这东西限制了多线程并发,对python而言是个弊大于利的存在。但是从stackoverflow上的讨论来看,这个存在还是相当有必要的。
- 增加了单线程的运行速度
- 可以更方便地整合一些线程不安全的C语言库到python里面去
首先单线程的运行速度更快了,因为有这个全局锁的存在,在执行单线程计算的时候不需要再额外增加锁,减少了不必要的开支。第二个则是可以更好地整合用C语言所写的python库。现在其实挺多用C语言写好底层计算然后封装提供python接口的,比如数据处理领域的pandas库,人工智能领域的计算框架Tensorflow或者pytorch,他们的底层计算都是用C语言写的。由于这个全局锁的存在,我们可以更方便(安全)地把这些C语言的计算库整合成一个python包,对外提供python接口。
## GIL对性能的影响大吗
对于需要做大量计算的任务而言,影响是相当大的。我们先来看一段单线程代码:
```python
class A(object):
def run(self):
ans = 0
for i in range(100000000):
ans += i
a = A()
for _ in range(5):
a.run()
```
以上这段代码是跑5次计算,每次计算是从1累加到1千万,跑这段代码需要17.46s。
紧接着,我们用python的多线程库来实现一个多线程计算:
```python
import threading
class A(object):
def run(self):
ans = 0
for i in range(100000000):
ans += i
threads = []
for _ in range(5):
a = A()
th = threading.Thread(target=a.run)
th.start()
threads.append(th)
for th in threads:
th.join()
```
这里我们启动了5个线程同时计算,然后我们又测试下时间: **41.35**秒!!!这个时候GIL的问题就体现出来了,我们通过多线程来实现并发,结果比单线程慢了2倍多。
### 一个神奇的修饰符
话不多说,我们先来看下代码。以下这段代码和上面的多线程代码几乎一样。但是我们要注意到,在类A的定义上面,我们增加了一个修饰符*@parl.remote_class*。
```python
import threading
import parl
@parl.remote_class
class A(object):
def run(self):
ans = 0
for i in range(100000000):
ans += i
threads = []
parl.connect("localhost:6006")
for _ in range(5):
a = A()
th = threading.Thread(target=a.run)
th.start()
threads.append(th)
for th in threads:
th.join()
```
现在我们来看下计算时间:**3.74秒**!!!相比于单线程的17.46s,这里只用了接近1/5的时间(因为我们开了5个线程)。这里是我觉得比较神奇的地方,并没有做太多的改动,只是在我的单线程类上面增加了一个修饰符,然后用原生的python多线程继续跑代码就变得相当快了。
### 完整的使用说明:
1. 安装这个库:
```shell
pip install --upgrade git+https://github.com/PaddlePaddle/PARL.git
```
2. 在本地通过命令启动一个并发服务(只需要启动一次)
```shell
xparl start --port 6006
```
3. 写代码的时候通过修饰符修饰你要并发的类@parl.remote。
这里需要注意的是只有经过这个修饰符修饰的类才可以实现并发。
4. 在代码最开始的时候通过parl.connect('localhost:6006')来初始化这个包。
最后贴下这个库的使用文档:
https://parl.readthedocs.io/en/latest/parallel_training/setup.html
源码在这里:
https://github.com/PaddlePaddle/PARL/tree/develop/parl/remote
后续会继续研究源码,看下是怎么做到一个修饰符就能加速的。大家如果读过了源码可以一起讨论下:)
c语言多线程转python多线程,真正的python 多线程!一个修饰符让你的多线程和C语言一样快...相关推荐
- c语言编程改变旅馆价格,模拟旅馆管理系统的一个功能——床位的分配与回收(c语言编程)...
模拟旅馆管理系统的一个功能--床位的分配与回收 题目:模拟旅馆管理系统的一个功能--床位的分配与回收 ⒈问题描述: 某旅馆有n个等级的房间,第I等级有 个房间,每个等级有个床位(1≤I≤n).试模拟旅 ...
- [python 进阶] 9. 符合Python风格的对象
文章目录 9.1 对象表示形式 9.2 再谈向量类 9.3 备选构造方法 9.4 classmethod与staticmethod 9.5 格式化显示 9.6 可散列的Vector2d 什么是可散列的 ...
- python中@修饰符用法
@修饰符 '@'符号用作函数修饰符是python2.4新增加的功能,修饰符必须出现在函数定义前一行,不允许和函数定义在同一行.也就是说@A def f(): 是非法的. 只可以在模块或类定义层内对函 ...
- python @修饰符_Python基础(面向对象之类成员与修饰符)
本篇将介绍Python 类的成员.类成员修饰符.类的特殊成员. 类的成员可以分为三大类:字段.方法.属性 1.字段: 也可理解为变量,分为: 普通字段:保存在对象中,访问时通过"对象.字段名 ...
- PHP从零开始--字段修饰符数据操作SQL语言
文章目录 一. 字段修饰符 1.1主键 1.2自动增长 1.3非空 1.4默认值 1.5外键 二. 对数据的操作 2.1增加数据 2.2删除数据 2.3更新数据 2.4查询数据 2.4.1查询所有的数 ...
- Python修饰符--函数修饰符 “@”
Python函数修饰符,"@",与其说是修饰函数倒不如说是引用.调用它修饰的函数. 举个栗子,下面的一段代码,里面两个函数,没有被调用,也会有输出结果: def test(f):p ...
- 视频教程-Python数据分析与爬虫-Python
Python数据分析与爬虫 10年一线开发及项目管理经验,6年以上大数据项目架构.实施.开发与运维经验,骨灰级大数据玩家,对Hadoop.Storm.Spark.Flink.Kylin.Druid等大 ...
- python豆瓣电影需研究的问题_python爬虫获取豆瓣电影——多线程问题
25 May 2015 GIL全称Global Interpreter Lock(全局解释器锁),它是在实现Python解析器(CPython)时所引入的一个概念.但是它并不是Python的特性.Py ...
- 【python第三方库】python多线程编程---threading库
文章目录 一.python多线程 1. GIL 二.threading库使用介绍 1. 创建多线程 2. 线程合并 3. 线程同步与互斥锁Lock 4. 死锁与可重入锁(递归锁)RLock 5. 守护 ...
最新文章
- 介绍一个.Net资源站点
- 这几个公众号带你看看BAT的工作情况
- 阿里rocketmq与自建rocketmq
- python读取配置文件获取所有键值对_Python读取properties配置文件操作示例
- 【转】20个Java 代码生成器
- matlab ifft频率分辨率,matlab中关于FFT的使用(理解频率分辨率、补零问题)
- sublime text3 boxy主题 (本地 压缩包 安装)
- virsh、qemu-img基本管理操作
- 职场人必看:提高工作效率的6大法则
- (一)OSG初学者入门基础教程
- 使用A*算法求最短路径
- pytorch之torch.gather方法
- vivado时序约束
- 接招吧,最强“高并发”系统设计 46 连问,分分钟秒杀一众面试者
- S1000D数据模块类型中英文对照
- 猪圈密码(Pigpen)
- 公安大数据与图侦应用结合现状分析
- 设计师必备取色技巧!教你在PS里通过照片创建色板
- 山东高新技术企业申报当年下证的知识产权能用吗?
- json的dump和dumps的区别