相关文章推荐
含蓄的作业本  ·  java object转化为数组 - CSDN文库·  11 月前    · 
傻傻的针织衫  ·  分布式事务原理及解决方案 - 夏尔_717 ...·  1 年前    · 
侠义非凡的剪刀  ·  图片中添加点击事件后没有反应的问题分析_图片 ...·  1 年前    · 
想发财的遥控器  ·  iOS 动态更新App图标和App内评分 - 简书·  1 年前    · 
八块腹肌的西装  ·  select union ...·  2 年前    · 
Code  ›  Python多核编程分析开发者社区
https://cloud.tencent.com/developer/article/2162163
潇洒的雪糕
1 年前
mythsman

Python多核编程分析

前往小程序,Get 更优 阅读体验!
立即前往
腾讯云
开发者社区
文档 建议反馈 控制台
首页
学习
活动
专区
工具
TVP
最新优惠活动
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
mythsman
首页
学习
活动
专区
工具
TVP 最新优惠活动
返回腾讯云官网
社区首页 > 专栏 > Python多核编程分析

Python多核编程分析

作者头像
mythsman
发布 于 2022-11-14 16:01:55
1.1K 0
发布 于 2022-11-14 16:01:55
举报
文章被收录于专栏: mythsman的个人博客 mythsman的个人博客

简述

之前一直都用python的多线程库(比如threading)来写一些并发的代码,后来发现其实用这个方法写的程序其实并不是真正的并行(parrallel)计算,而只是利用单个CPU进行的并发(concurrency)计算。因此,多线程也仅仅只在处理一些被频繁阻塞的程序时才会有效率上的提升,比如网络爬虫里等待http返回等;而在CPU使用密集的程序里使用多线程反而会造成效率的下降。那么为什么python不把threading库设计成并发的线程呢?这是因为python本身有一个全局翻译锁,叫GIL(Global Interpreter Lock),这个锁的目的是让当前的python解释器在同一时间只能执行一条语句,从而保证程序的正确运行,这也就导致了一个python解释器只能并发处理而不能并行处理。那么,如果想并行的执行代码,显然需要开启多个python解释器,这也就不是多线程,而是多进程了,因此python在多线程库里并不支持多核处理,而是在多进程库(multiprocessing)里支持多核处理。

多线程编程:

多线程编程比较简单,主要利用threading类即可:

代码语言: javascript
复制
import threading
mutex = threading.Lock()
def little_thread(arg):
	print 'Thread %d start.'%(arg)
	mutex.acquire()
	#critical area
	mutex.release()
	while True:
		arg*=arg
def test():
	threads=[]
	thread_num=4
	for i in range(thread_num):
		t=threading.Thread(target=little_thread,args=(i,))
		t.start()
		threads.append(t)
	for t in threads:
		t.join()
if __name__=='__main__':
	test()

基本用法也就是把执行逻辑的函数传给Thread对象,并用tuple的形式传进参数,然后start就可以开始线程,最后join阻塞等待线程结束。

同时,也可以自定义锁,来保护共享数据或者临界区。

这里注意到我在死循环里写的不是空语句,而是一个较为复杂的计算,这是因为如果写的不是空语句,那么操作系统可能会对线程进行优化,导致效果不理想。

我把上面的代码运行在一个四核的机器上,用htop工具查看各个cpu的占用情况:

我们发现这四个核基本只有一个核在全速运行,其他的三个核基本没有工作,这就说明了多线程其实并没有真正用到多个核。

多进程编程

多进程编程方法其实和多线程类似,只是需要注意多进程的各个子进程无法直接访问父进程内的公共变量(毕竟已经是一个独立的进程了,有自己的数据段)。为了解决这个问题,就需要用到一个Manager来管理共享变量:

代码语言: javascript
复制
import multiprocessing
#shared variable
output_line=multiprocessing.Manager().list()
def little_process(arg):
	print 'Process %d start.'%(arg)
	output_line.append(arg)
	while True:
def test():
	processes=[]
	process_num=4
	for i in range(process_num):
		t=multiprocessing.Process(target=little_process,args=(i,))
		t.start()
		processes.append(t)
	for t in processes:
 
推荐文章
含蓄的作业本  ·  java object转化为数组 - CSDN文库
11 月前
傻傻的针织衫  ·  分布式事务原理及解决方案 - 夏尔_717 - 博客园
1 年前
侠义非凡的剪刀  ·  图片中添加点击事件后没有反应的问题分析_图片点击事件为什么触发不了-CSDN博客
1 年前
想发财的遥控器  ·  iOS 动态更新App图标和App内评分 - 简书
1 年前
八块腹肌的西装  ·  select union all合并后再汇总数据-掘金
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号