跳转到主要内容

基于Twisted线程池的阻塞API包装器。

项目描述

https://travis-ci.org/lvh/thimble.svg https://coveralls.io/repos/lvh/thimble/badge.png https://dl.dropboxusercontent.com/u/38476311/Logos/thimble.jpg

thimble是一个用于安全地玩针和线的工具。这个库,thimble,通过线程池的方式将具有阻塞API的对象包装成一个非阻塞、Twisted友好的Deferred API。

快速开始

您感兴趣的主要对象是thimble.Thimble。它接受一个线程池、一个阻塞对象以及您希望延迟到线程池中的方法名称列表。

这是我们的示例阻塞对象

>>> class Car(object):
...     wheels = 4
...     def drive_to(self, location):
...          # Assume the real implementation blocks.
...          return "driven to {0}".format(location)
>>> car = Car()

出于演示目的,我们将使用线程池和reactor的测试双倍;在实际代码中,您将希望使用真实的东西。

>>> from thimble.test.util import FakeThreadPool, FakeReactor
>>> pool = FakeThreadPool()
>>> reactor = FakeReactor()

池尚未启动。(我们将在下一分钟看到这为什么很重要。)

>>> pool.started
False

创建一个Thimble

>>> from thimble import Thimble
>>> car_thimble = Thimble(reactor, pool, car, ["drive_to"])

当访问列表中的方法时,您将获得一个包装它的对象。调用它返回一个Deferred对象。任何传递的参数都将原样传递给包装的方法。

>>> def print_(s):
...     # can't use from __future__ import print_function because of a
...     # doctest limitation :-(
...     print s
>>> d = car_thimble.drive_to("work").addCallback(print_)
driven to work

由于我们使用的是伪造的线程池和反应器,所以这个Deferred对象已经同步触发。

您可以直接在Thimble上访问包装对象的其它属性。

>>> car.wheels
4

如果传递给Thimble的线程池在第一次尝试使用它之前尚未启动,Thimble将启动它并安排其关闭。如果您传递一个已经启动的线程池,您将负责其关闭。在这种情况下,线程池尚未启动,所以Thimble为您启动了它。

>>> pool.started
True

关闭反应器,反应器将在自身关闭之前要求线程池停止。

>>> reactor.stop()
>>> pool.started
False

在您的代码中使用thimble

线程池

您可以选择使用反应器线程池,或者创建您自己的线程池。

使用反应器线程池可能是一个坏主意。默认情况下,反应器线程池被许多软件共享,并且也用于DNS解析。如果您的软件阻塞了池中所有的可用线程(无论是意外还是由于错误),这将影响DNS解析,进而可能影响许多其他系统;如果它没有直接影响这些系统(因为它们也想使用反应器线程池)。

由于以下两个原因,为每个应用程序拥有一个专门的线程池可能更可靠

  • 应用程序可能最清楚线程池的理想大小。

  • 这是放置全局状态的适当状态:如果您将其放入库中,同一进程中不同用户使用该库可能会相互冲突。

不幸的是,共享的全局状态基本上是这样做的

from twisted.python.threadpool import ThreadPool
_the_thread_pool = _ThreadPool()

请参阅ThreadPool类的文档以获取更多详细信息;它允许您指定线程的最小和最大数量。默认值可能相当合理。

并发和线程安全

您指定线程池拥有的线程数是尝试并发访问您的对象的线程数。确保对象实际上是线程安全的取决于您。

如果您想为非线程安全的对象提供一个非阻塞的API,只需将线程池中的线程数限制为1,这将导致完全同步的访问。请注意,对于不在blocking_methods列表中的任何属性名,其属性访问仍然由调用线程同步执行。

入口点

虽然子类化Thimble可能会意外地工作,但并不推荐。我保留更改实现的权利,这可能破坏这一点:例如,通过引入元类。

编写一个小的实用函数可能更好,该函数要么构建一个新的使用共享线程池的Thimble,要么总是返回同一个thimble。

变更日志

Thimble使用SemVer

v0.2.0

  • 对tox CI设置进行了少量更新

  • 升级了依赖项

v0.1.1

  • 添加了这个变更日志

  • 拼写修正

  • 添加了.gitignore

  • 大量的文档改进

v0.1.0

首次公开发布。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

thimble-0.2.0.tar.gz (8.5 kB 查看哈希值)

上传时间

构建分发

thimble-0.2.0-py2-none-any.whl (11.9 kB 查看哈希值)

上传时间 Python 2

由以下支持