我应该使用什么压缩 – 解压缩Python模块来构建一个系统,其中Google App Engine(Python 2.7)与Linux机器上的应用程序交换压缩数据? 还有两个额外的限制: > Linux机器和GAE都将进行压缩/解压缩,并且需要安全地操作线程; 我问,因为从文档中不清楚某些[de]压缩模块是否是线程安全的. 任何人都可以帮忙填写压缩模块表吗? > bz2:IS SAFE,每个:http://docs./2/library/bz2.html,但有一个关于个别锁定的评论让我想知道我是否需要明确管理锁. 谢谢! 编辑(回答abarnert的问题): > RAM与类文件对象= App Engine不提供打开类文件对象的方法(除非文件是作为应用程序的一部分上传的).因此,如果GAE从Linux盒子中获取压缩数据,如果压缩模块坚持要通过类似文件的对象,我不知道如何解压缩它.例如,gzip模块坚持使用文件名:http://docs./2/library/gzip.html 解决方法: 你的问题基本上没有意义,因为你误解了一些基本的东西并产生了不存在的问题.我试着在评论中回答,但是你可以用这种方式做限,所以…
对于类文件对象,您不需要文件名或文件.这就是文件类对象背后的整个想法.
不,您仍然混淆文件对象和类文件对象. A file object表示磁盘上的实际文件. GAE限制了那些.类似文件的对象是具有相同API的任何对象,即一个像文件一样的对象,而不必(实际上)是一个. GAE没有做任何事情来阻止您创建类似文件的对象. – 类文件对象( 因此,您可以像这样编写一个类似文件的对象:
或者,如果你在内存中有一个缓冲区,并且你希望能够像文件一样从中读取:
但是,在许多情况下,Python / GAE已经为您提供了一个类似文件的对象,您可以按原样使用它,而无需将其读入缓冲区并将其包装在另一个类似文件的对象中.许多网络API为您提供类似文件的对象,但不是全部. 例如,如果调用urllib2.urlopen,则结果是类文件对象;如果你调用urlfetch.fetch,它不是,所以如果你需要的话,你必须使用StringIO(response.content).
如果它坚持使用类似文件的对象,请为其提供类似文件的对象.创建实际文件是一种方法,但不是唯一的方法.如果你有一个urllib2.urlopen响应,那就试试吧.如果内存中有缓冲区,只需将其包装在StringIO中即可.等等.
不,不.阅读您链接到的文档:
请注意,有一个fileobj参数以及一个文件名参数?文档的第一行说:
因此,除非fileobj为None,否则它不会坚持使用文件名.为了解决这个问题,请…不要为fileobj传递None. fileobj必须是真正的文件对象,还是可以是另一个类似文件的对象?那么,下一段说:
所以,你去吧. 不幸的是,Python 2.x对于什么算作类似文件的对象并不是100%一致,并且文档并不总是很清楚. (这在3.x中被清理了很多,但是如果你使用GAE,这对你没有任何好处.) 如果某些API不喜欢您的类文件对象,因为它不能模拟足够的API,您将通过获取AttributeError找到答案.例如,您可能会收到一条错误消息,指出您从urllib2.urlopen返回的对象没有seek属性. 解决方法很简单:将其读入内存并创建StringIO.换句话说,只需将fileobj = my_file_obj更改为fileobj = StringIO(my_file_obj.read()). 另请注意,GzipFile本身就是一个类文件对象.这很重要,因为这意味着你可以将事物链接在一起 – 你可以用StringIO创建一个GzipFile,然后用GzipFile创建一个TarFile,依此类推.
那不是问题.再次,阅读您链接到的文档:
压缩和/或解压缩多个独立的LZMAFile实例不是问题.只有当您想要跨线程共享相同的实例时.并且几乎没有充分的理由这样做.
您所谈论的所有压缩机都是流式压缩机.在不压缩文件的情况下,无法从文件中间解压缩任意块. 这对我来说意味着你实际拥有的是一堆独立压缩的块(无论是在单独的文件中,还是连接成一个文件都不清楚,但并不重要). 这意味着您无需在任何地方共享解压缩程序或压缩程序.例如:
线程之间没有什么可以分享的.即使200个线程同时执行此操作,即使其中100个线程正在尝试处理相同的块文件,仍然不会出现问题.唯一需要排序的是最后的send_to_gae.
在不了解您的代码的情况下,调试它非常困难,但我有一个很好的猜测:您通过写入临时文件来进行压缩,而不是在
不可否认,它有点令人困惑.它只是说: >螺纹安全使用单独的锁定机制. 这显然意味着它的线程安全,但为什么你关心它们使用什么锁定机制?什么是“个人锁定机制”呢? 你只能看看the source). 它们的意思是每个BZ2Compressor(和BZ2Decompressor)对象都有自己独立的锁,因此其中一个可以锁定而不会影响其他对象. 如果您还没有处理Python C扩展中的线程,您可能无法理解这是什么.通常,在Python中,每个线程都需要保持GIL才能完成任何工作,这意味着一次只能运行一个线程.但是C扩展模块可以释放GIL,同时使用非Python对象(例如,压缩大缓冲区)进行CPU繁重的工作.如果N个线程释放GIL,则最多可以并行运行N 1个线程,这意味着您可以在不运行多个进程的情况下从您的8核CPU中获得很大的优势.但是,除非用锁保护它们,否则在释放GIL时不能触摸任何Python对象. 许多发布GIL以加速的模块会创建一个模块锁(有时因为找出代码可能触及的对象并不容易).这意味着你可以运行一个线程来执行该模块的东西,并与执行其他操作的线程并行执行,但不会有多个线程执行该模块的操作. 但是,如果每个线程只需要触摸单个对象,则可以为每个对象使用不同的锁,这意味着您可以并行运行任意数量的线程,只要它们都在处理不同的对象. 如果你试图同时在两个线程中使用同一个对象,它不会破坏任何东西;你将最终得到一个线程等待获取锁定,直到另一个完成(这比等待GIL更好或更差). 来源:https://www./content-3-280451.html |
|