1.0.2版修订版

This commit is contained in:
XiongNeng
2016-01-21 10:40:40 +08:00
parent d31aa5a086
commit 21bb590999
6 changed files with 19 additions and 13 deletions

View File

@@ -31,7 +31,7 @@
当你创建好一个线程对象后,该对象并不会立即执行,除非你调用它的 ``start()`` 方法(当你调用 ``start()`` 方法时它会调用你传递进来的函数并把你传递进来的参数传递给该函数。Python中的线程会在一个单独的系统级线程中执行比如说一个 POSIX 线程或者一个 Windows 线程),这些线程将由操作系统来全权管理。线程一旦启动,将独立执行直到目标函数返回。你可以查询一个线程对象的状态,看它是否还在执行:
.. code-block:: python
if t.is_alive():
print('Still running')
else:
@@ -47,7 +47,7 @@ Python解释器在所有线程都终止后才继续执行代码剩余的部分
例如:
.. code-block:: python
t = Thread(target=countdown, args=(10,), daemon=True)
t.start()
@@ -79,7 +79,7 @@ Python解释器在所有线程都终止后才继续执行代码剩余的部分
例子如下:
.. code-block:: python
class IOTask:
def terminate(self):
self._running = False
@@ -106,7 +106,7 @@ Python解释器在所有线程都终止后才继续执行代码剩余的部分
有时你会看到下边这种通过继承 ``Thread`` 类来实现的线程:
.. code-block:: python
from threading import Thread
class CountdownThread(Thread):
@@ -126,7 +126,7 @@ Python解释器在所有线程都终止后才继续执行代码剩余的部分
尽管这样也可以工作,但这使得你的代码依赖于 ``threading`` 库,所以你的这些代码只能在线程上下文中使用。上文所写的那些代码、函数都是与 ``threading`` 库无关的,这样就使得这些代码可以被用在其他的上下文中,可能与线程有关,也可能与线程无关。比如,你可以通过 ``multiprocessing`` 模块在一个单独的进程中执行你的代码:
.. code-block:: python
import multiprocessing
c = CountdownTask(5)
p = multiprocessing.Process(target=c.run)

View File

@@ -50,7 +50,7 @@
event 对象最好单次使用,就是说,你创建一个 event 对象,让某个线程等待这个对象,一旦这个对象被设置为真,你就应该丢弃它。尽管可以通过 ``clear()`` 方法来重置 event 对象,但是很难确保安全地清理 event 对象并对它重新赋值。很可能会发生错过事件、死锁或者其他问题(特别是,你无法保证重置 event 对象的代码会在线程再次等待这个 event 对象之前执行)。如果一个线程需要不停地重复使用 event 对象,你最好使用 ``Condition`` 对象来代替。下面的代码使用 ``Condition`` 对象实现了一个周期定时器,每当定时器超时的时候,其他线程都可以监测到:
.. code-block:: python
import threading
import time

View File

@@ -15,6 +15,7 @@
例如:
.. code-block:: python
from queue import Queue
from threading import Thread
@@ -103,7 +104,7 @@
使用队列来进行线程间通信是一个单向、不确定的过程。通常情况下,你没有办法知道接收数据的线程是什么时候接收到的数据并开始工作的。不过队列对象提供一些基本完成的特性,比如下边这个例子中的 ``task_done()````join()``
.. code-block:: python
from queue import Queue
from threading import Thread
@@ -138,7 +139,7 @@
如果一个线程需要在一个“消费者”线程处理完特定的数据项时立即得到通知,你可以把要发送的数据和一个 ``Event`` 放到一起使用这样“生产者”就可以通过这个Event对象来监测处理的过程了。示例如下
.. code-block:: python
from queue import Queue
from threading import Thread, Event
@@ -171,7 +172,7 @@
使用线程队列有一个要注意的问题是,向队列中添加数据项时并不会复制此数据项,线程间通信实际上是在线程间传递对象引用。如果你担心对象的共享状态,那你最好只传递不可修改的数据结构(如:整型、字符串或者元组)或者一个对象的深拷贝。例如:
.. code-block:: python
from queue import Queue
from threading import Thread
import copy
@@ -216,7 +217,7 @@
这些操作都可以用来避免当执行某些特定队列操作时发生无限阻塞的情况,比如,一个非阻塞的 ``put()`` 方法和一个固定大小的队列一起使用,这样当队列已满时就可以执行不同的代码。比如输出一条日志信息并丢弃。
.. code-block:: python
def producer(q):
...
try:
@@ -227,7 +228,7 @@
如果你试图让消费者线程在执行像 ``q.get()`` 这样的操作时,超时自动终止以便检查终止标志,你应该使用 ``q.get()`` 的可选参数 ``timeout`` ,如下:
.. code-block:: python
_running = True
def consumer(q):

View File

@@ -48,7 +48,7 @@
在一些“老的” Python 代码中,显式获取和释放锁是很常见的。下边是一个上一个例子的变种:
.. code-block:: python
import threading
class SharedCounter:

View File

@@ -16,6 +16,7 @@
是非常容易实现的,示例如下:
.. code-block:: python
import threading
from contextlib import contextmanager
@@ -50,6 +51,7 @@
示例如下:
.. code-block:: python
import threading
x_lock = threading.Lock()
y_lock = threading.Lock()
@@ -78,6 +80,7 @@
假设你的代码是这样写的:
.. code-block:: python
import threading
x_lock = threading.Lock()
y_lock = threading.Lock()
@@ -106,6 +109,7 @@
如果你运行这个版本的代码,必定会有一个线程发生崩溃,异常信息可能像这样:
.. code-block:: python
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.3/threading.py", line 639, in _bootstrap_inner
@@ -145,6 +149,7 @@
下面是一个简单的使用死锁避免机制解决“哲学家就餐问题”的实现:
.. code-block:: python
import threading
# The philosopher thread

View File

@@ -46,7 +46,7 @@
其他方法操作被存储为 ``self.local.sock`` 的套接字对象。
有了这些就可以在多线程中安全的使用 ``LazyConnection`` 实例了。例如:
::
.. code-block:: python
from functools import partial
def test(conn):