关于多线程是否在Python中工作,我有点困惑.
我知道有很多关于这方面的问题,我已经读了很多,但我仍然感到困惑.我从自己的经验中了解到并且已经看到其他人在StackOverflow上发布他们自己的答案和示例,在Python中确实可以实现多线程.那么为什么每个人都一直说Python被GIL锁定并且一次只能运行一个线程呢?它显然确实有效.或者是否有一些区别我没有到这里?
许多海报/受访者也一直提到线程有限,因为它没有使用多个核心.但我会说它们仍然有用,因为它们可以同时工作,从而更快地完成组合工作量.我的意思是为什么甚至会有一个Python线程模块呢?
更新:
谢谢你到目前为止的所有答案.我理解的方式是多线程只能并行运行某些IO任务,但一次只能运行一个CPU绑定的多个核心任务.
我不完全确定这对我来说在实际意义上是什么意思,所以我只举一个我想要多线程的任务的例子.例如,假设我想遍历很长的字符串列表,我想对每个列表项执行一些基本的字符串操作.如果我拆分列表,将每个子列表发送给我的循环/字符串代码在新线程中处理,并将结果发送回队列,这些工作负载会大致同时运行吗?最重要的是,理论上这会加快运行脚本所需的时间吗?
另一个例子可能是如果我可以在四个不同的线程中使用PIL渲染和保存四个不同的图片,并且这比一个接一个地逐个处理图片更快?我想这个速度组件是我真正想知道的,而不是正确的术语.
我也知道多处理模块,但我现在主要关心的是中小型任务负载(10-30秒),所以我认为多线程会更合适,因为子进程可能很慢启动.
(这个问题是关于如何使多处理.Pool()更快地运行代码.我终于解决了它,最后的解决方案可以在帖子的底部找到.)
原始问题:
我正在尝试使用Python将单词与列表中的许多其他单词进行比较,并检索最相似的单词列表.为此,我使用difflib.get_close_matches函数.我使用的是Python 2.6.5相对较新且功能强大的Windows 7笔记本电脑.
我想要的是加快比较过程,因为我的比较单词列表很长,我不得不多次重复比较过程.当我听说多处理模块时,似乎合乎逻辑的是,如果比较可以分解为工作任务并同时运行(从而利用机器功率换取更快的速度),我的比较任务将更快完成.
然而,即使在尝试了许多不同的方法,并使用了文档中显示并在论坛帖子中建议的方法之后,Pool方法似乎非常慢,比在整个列表上运行原始get_close_matches函数慢得多.一旦.我想帮助理解为什么Pool()如此缓慢以及我是否正确使用它.我只使用这个字符串比较方案作为一个例子,因为这是我能想到的最新例子,我无法理解或者让多处理工作而不是反对我.下面是difflib场景中的一个示例代码,显示了普通方法和Pooled方法之间的时间差异:
from multiprocessing import Pool
import random, time, difflib
# constants
wordlist = ["".join([random.choice([letter for letter in "abcdefghijklmnopqersty"]) for lengthofword in xrange(5)]) for nrofwords in xrange(1000000)]
mainword = "hello"
# comparison function
def findclosematch(subwordlist):
matches = difflib.get_close_matches(mainword,subwordlist,len(subwordlist),0.7)
if matches <> []:
return matches
# pool
print "pool method"
if __name__ == '__main__':
pool = Pool(processes=3)
t=time.time()
result = pool.map_async(findclosematch, wordlist, chunksize=100)
#do something with result
for r in result.get():
pass
print time.time()-t
# normal …
Run Code Online (Sandbox Code Playgroud) 问题
我最近在这个链接中找到了一个很棒的纯Python-ray光线跟踪脚本,并为了更方便的功能而扩展了一点.然而,有时它会扭曲物体的形状,我想知道有光线追踪/ 3D经验的人是否可能有任何线索可能导致它?
一些信息
我正在测试的场景包括一个地面平面,顶部有三个彩色球体.当相机从上方/角度和一定距离俯视场景时,它会产生美观的场景(参见前两张照片); 然而,当相机靠近地面并靠近物体时,球体最终会改变它们的形状并变成椭圆形,好像它们被拉向天空一样(见第三张图片).请注意,带有扭曲球体的第三张照片中的相机有点颠倒,这是因为我还在弄清楚如何控制相机而不确定如何在发生这种情况时"直立"旋转它.它似乎自动地朝向球体/光源所在的一般区域看,并且只有当我改变一些参数时它才会朝不同的方向看.
我仍然试图破译并理解我发现的原始代码中的内容以及我的代码所基于的内容,所以我不知道,但它可能是原始作者采用光线追踪的方法或方法.我已经附加了我的模块脚本的整个代码,当你按F5时,如果有人接受挑战,它应该运行.图像渲染需要PIL,如果您想要使用摄像机的位置,只需查看Camera类,并在"normaltest"功能中更改其选项.
更新
有人指出,在运行脚本时,它不会在第三张图像中重现问题.我现在已经更改了正常测试功能的摄像头位置,以便重现问题(请参阅新的第四张图像,看看它应该是什么样子).如果你想知道为什么光似乎是从球体中射出来的,那么我就把光源放在它们之间的某个地方.
我开始认为问题在于相机而我完全不了解它.
还要尝试将相机从当前的z坐标2增加到5的az,这是一个非常小的变化,但它会使失真看起来更好看(尽管仍然很糟糕),因此接近地面或角度的变化随之而来它似乎发挥了一些作用.
"""
Pure Python ray-tracer :)
taken directly from http://pastebin.com/f8f5ghjz with modifications
another good one alternative at http://www.hxa.name/minilight/
some more equations for getting intersection with other 3d geometries, https://www.cl.cam.ac.uk/teaching/1999/AGraphHCI/SMAG/node2.html#SECTION00023200000000000000
"""
#IMPORTS
from math import sqrt, pow, pi
import time
import PIL,PIL.Image
#GEOMETRIES
class Vector( object ):
def __init__(self,x,y,z):
self.x = x
self.y = y
self.z = z
def dot(self, b):
return self.x*b.x + …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Windows 中的 Freetype 文本渲染支持为 Python 2,7 编译 Aggdraw 绘图模块。问题是,即使我按本书做所有事情,我仍然收到错误消息,提示没有字体渲染器:
Traceback (most recent call last):
File "C:\Users\BIGKIMO\Desktop\fdsfdf.py", line 9, in <module>
font = Font('black', r'C:\Windows\Fonts\Georgia.ttf')
IOError: cannot load font (no text renderer)
Run Code Online (Sandbox Code Playgroud)
我已经阅读了以前的帖子,因此执行以下步骤:
cd path/to/folder/of/setup.py
,然后python setup.py install
安装脚本似乎接受了我提供的 freetype 位置,并且不会抱怨 freetype 被禁用,所以我认为 Aggdraw Freetype 支持已安装。
我已经在 Mac 上尝试过同样的方法,使用 64 位版本的 Aggdraw,编译 Freetype,编译 Aggdraw 并链接到 Freetype,但仍然不会让我绘制文本。
这是我用来测试文本渲染的代码,尽管这应该不是问题:
from PIL import Image
from aggdraw import Draw, Brush, …
Run Code Online (Sandbox Code Playgroud) 我想在 Python (2.7) Tkinter GUI 应用程序(在 Windows 7 PC 上)中嵌入 Cartopy 模块映射,但我需要帮助来弄清楚如何实现。
据我了解,Cartopy 模块只是使 matplotlib 将其“绘图”或绘图视为坐标并将其投影到现实世界的地理投影。现在我已经看到了有关如何将 matplotlib 嵌入到 Tkinter 中的问题和指南,但这些总是涉及创建 matplotlib 图(),然后在该图上使用 show() 方法和FigureCanvasTkAgg(),而创建 cartopy 地图的说明通常是简单地使用 pyplot 的axes()方法,同时提供cartopy投影对象,然后将show()与pyplot模块(而不是Figure对象)一起使用。我尝试了一些不同的方法,但我无法理解如何协调这两种方法(创建 cartopy matplotlib 并在 Tkinter 中嵌入 matplotlib)。我有制图、Python 和 Tkinter 方面的经验,但我对 matplotlib 和 cartopy 还很陌生,所以可能我对这些模块还不够了解。
如果有人可以建议一个具体的代码示例以及他们的答案,那将是最有帮助的。如果能看到一个示例,说明如何在新的嵌入式 cartopy 地图中绘制线或点,例如我应该在哪个对象上使用 .plot() 方法,那就太好了?
从长远来看,希望能够通过 Tkinter GUI 应用程序与 cartopy 地图进行交互。顺便说一句,以前有人做过这样的 cartopy Tkinter 嵌入吗?
---> 回答:感谢@Pelson 的回答,并提供了代码示例。对于其他遇到同样问题的人来说,据我了解,关键步骤是 1)创建一个 matplot 图形,2)通过包含投影参数向图形添加轴(从而使其成为 Cartopy 轴),以及 3)转换图形通过使用FigureCanvasTkAgg 函数将其添加到 Tkinter 小部件,然后使用其 show() 和 get_tk_widget() 方法将小部件打包或放置在 Tkinter 窗口中。
python ×5
3d ×1
aggdraw ×1
cartopy ×1
embed ×1
freetype ×1
graphics ×1
matplotlib ×1
performance ×1
pool ×1
raytracing ×1
tkinter ×1