python _thread模块使用
python关于线程管理的有2个类,_thread(在2.x的版本中叫thread)和threading。
# encoding: UTF-8
import thread
import time
# 一个用于在线程中执行的函数
def func():
for i in range(5):
print 'func'
time.sleep(1)
# 结束当前线程
# 这个方法与thread.exit_thread()等价
thread.exit() # 当func返回时,线程同样会结束
# 启动一个线程,线程立即开始运行
# 这个方法与thread.start_new_thread()等价
# 第一个参数是方法,第二个参数是方法的参数
thread.start_new(func, ()) # 方法没有参数时需要传入空tuple
# 创建一个锁(LockType,不能直接实例化)
# 这个方法与thread.allocate_lock()等价
lock = thread.allocate()
# 判断锁是锁定状态还是释放状态
print lock.locked()
# 锁通常用于控制对共享资源的访问
count = 0
# 获得锁,成功获得锁定后返回True
# 可选的timeout参数不填时将一直阻塞直到获得锁定
# 否则超时后将返回False
if lock.acquire():
count += 1
# 释放锁
lock.release()
# thread模块提供的线程都将在主线程结束后同时结束
time.sleep(6)
输出:
Falsefunc
0
func 1
func 2
func 3
func 4
thread 模块提供的其他方法:
thread.interrupt_main(): 在其他线程中终止主线程。
thread.get_ident(): 获得一个代表当前线程的魔法数字,常用于从一个字典中获得线程相关的数据。这个数字本身没有任何含义,并且当线程结束后会被新线程复用。
thread还提供了一个ThreadLocal类用于管理线程相关的数据,名为 thread._local,threading中引用了这个类。
由于thread提供的线程功能不多,无法在主线程结束后继续运行,不提供条件变量等等原因,一般不使用thread模块,这里就不多介绍了。
python官网文档:
This module provides low-level primitives for working with multiple threads (also called light-weight processes or tasks) — multiple threads of control sharing their global data space. For synchronization, simple locks (also called mutexes or binary semaphores) are provided. The threading module provides an easier to use and higher-level threading API built on top of this module.
The module is optional. It is supported on Windows, Linux, SGI IRIX, Solaris 2.x, as well as on systems that have a POSIX thread (a.k.a. “pthread”) implementation. For systems lacking the _thread module, the _dummy_thread module is available. It duplicates this module’s interface and can be used as a drop-in replacement.
It defines the following constant and functions:
- exception _thread.error
- Raised on thread-specific errors.
- _thread.LockType
- This is the type of lock objects.
- _thread.start_new_thread(function, args[, kwargs])
- Start a new thread and return its identifier. The thread executes the function function with the argument list args (which must be a tuple). The optional kwargs argument specifies a dictionary of keyword arguments. When the function returns, the thread silently exits. When the function terminates with an unhandled exception, a stack trace is printed and then the thread exits (but other threads continue to run).
- _thread.interrupt_main()
- Raise a KeyboardInterrupt exception in the main thread. A subthread can use this function to interrupt the main thread.
- _thread.exit()
- Raise the SystemExit exception. When not caught, this will cause the thread to exit silently.
- _thread.allocate_lock()
- Return a new lock object. Methods of locks are described below. The lock is initially unlocked.
- _thread.get_ident()
- Return the ‘thread identifier’ of the current thread. This is a nonzero integer. Its value has no direct meaning; it is intended as a magic cookie to be used e.g. to index a dictionary of thread-specific data. Thread identifiers may be recycled when a thread exits and another thread is created.
- _thread.stack_size([size])
- Return the thread stack size used when creating new threads. The optional size argument specifies the stack size to be used for subsequently created threads, and must be 0 (use platform or configured default) or a positive integer value of at least 32,768 (32kB). If changing the thread stack size is unsupported, a ThreadError is raised. If the specified stack size is invalid, aValueError is raised and the stack size is unmodified. 32kB is currently the minimum supported stack size value to guarantee sufficient stack space for the interpreter itself. Note that some platforms may have particular restrictions on values for the stack size, such as requiring a minimum stack size > 32kB or requiring allocation in multiples of the system memory page size - platform documentation should be referred to for more information (4kB pages are common; using multiples of 4096 for the stack size is the suggested approach in the absence of more specific information). Availability: Windows, systems with POSIX threads.
Lock objects have the following methods:
- lock.acquire([waitflag])
- Without the optional argument, this method acquires the lock unconditionally, if necessary waiting until it is released by another thread (only one thread at a time can acquire a lock — that’s their reason for existence). If the integer waitflag argument is present, the action depends on its value: if it is zero, the lock is only acquired if it can be acquired immediately without waiting, while if it is nonzero, the lock is acquired unconditionally as before. The return value is True if the lock is acquired successfully, False if not.
- lock.release()
- Releases the lock. The lock must have been acquired earlier, but not necessarily by the same thread.
- lock.locked()
- Return the status of the lock: True if it has been acquired by some thread, False if not.
In addition to these methods, lock objects can also be used via the with statement, e.g.:
import _thread a_lock = _thread.allocate_lock() with a_lock:
print("a_lock is locked while this executes")
Caveats:
Threads interact strangely with interrupts: the KeyboardInterrupt exception will be received by an arbitrary thread. (When thesignal module is available, interrupts always go to the main thread.)
Calling sys.exit() or raising the SystemExit exception is equivalent to calling _thread.exit().
Not all built-in functions that may block waiting for I/O allow other threads to run. (The most popular ones (time.sleep(),file.read(), select.select()) work as expected.)
It is not possible to interrupt the acquire() method on a lock — the KeyboardInterrupt exception will happen after the lock has been acquired.
When the main thread exits, it is system defined whether the other threads survive. On SGI IRIX using the native thread implementation, they survive. On most other systems, they are killed without executing try ... finally clauses or executing object destructors.
When the main thread exits, it does not do any of its usual cleanup (except that try ... finally clauses are honored), and the standard I/O files are not flushed.
转自:http://docs.python.org/3.1/library/_thread.html
------------------------------------------------------------------------------------------------------------------------
python中的多线程
Python中实现多线程有两种方式,一种基于_thread模块(在Python2.x版本中为thread模块,没有下划线)的start_new_thread()函数,另一种基于threading模块的Thread类。
其实Python的多线程编程不能真正利用多核的CPU,但是用开源模块使你的计算压力分布到多核CPU上.........
一.使用start_new_thread()实现线程,是比较底层的实现方式,所有线程共享他们global数据,为了达到同步,模块也提供了简单的锁机制
_thread.start_new_thread(function, args[, kwargs]) |
启动一个新的进程,并返回其标识符. 线程执行的函数需要的参数由args(必须为一个元组)提供,亦可通过可选参数kwargs提供关键字参数组 成的字典。当函数返回时,启动的线程也 停止退出。如果函数中存在未处理异常,会打印堆栈跟踪后线程停止退出(其他线程继续执行)。 |
其中线程标识符是一个非0整数,并没有直接意思,可以当作从一个线程组成的特殊字典中索引本线程的一个key,也可用_thread.get_ident()得到,在线程退出后,标识符会被系统回收。在线程执行过程中可以调用_thread.exit()终止本线程的执行。
import _thread
import time
def threadFunction(count):
for i in range(count):
print('进程id为%d的打印%d'%(_thread.get_ident(),i))
i-=1
time.sleep(0.1) def begin():
ident1=_thread.start_new_thread(threadFunction,(100,))
print('启动标识符为%d的进程'%(ident1,))
ident2=_thread.start_new_thread(threadFunction,(100,))
print('启动标识符为%d的进程'%(ident2,)) if __name__ == '__main__':
begin()
二.使用Thread类来实现多线程,这种方式是对_thread模块(如果没有_thread,则为dummy_threading)的高级封装,在这种方式下我们需创建新类继承threading.Thread,和java一样重写threading.Thread的run方法即可.启动线程用线程的start方法,它会调用我们重写的run方法.
class MyThread(threading.Thread):
'''只能重写__init__ 和 run 两个方法'''
def __init__(self,name):
threading.Thread.__init__(self)
self.name=name
self.bool_stop=False
def run(self):
while not self.bool_stop:
print('进程%s,于%s'%(self.name,time.asctime()))
time.sleep(1)
def stop(self):
self.bool_stop = True if __name__ == '__main__':
th1=MyThread('one')
th2=MyThread('two')
th1.start()
th2.start()
Thread类还定义了以下常用方法与属性:
Thread.getName() \Thread.setName() |
老方式用于获取和设置线程的名称,官方建议用Thread.name替代 |
Thread.ident |
获取线程的标识符。只有在调用start()方法执行后才有效,否则返回None。 |
Thread.is_alive() |
判断线程是否是激活的。 |
Thread.join([timeout]) |
调用Thread.join将会使主调线程堵塞,直到被调用线程运行结束或超时。参数timeout是一个数值类型,表示超时时间,如果未提供该参数,那么主调线程将一直堵塞到被调线程结束。 |
Python中的锁
先用_thread模块的Lock锁来实现生产者消费者问题,Lock对象是Python提供的低级线程控制工具,使用起来非常简单,只需下面3条语句即可:
_thread.allocate_lock()返回一个新Lock对象,即为一个新锁 |
lock.acquire() 相当于P操作,得到一个锁, |
lock.release()相当于V操作,释放一个锁 |
代码如下:
import _thread,time,random
dish=0
lock = _thread.allocate_lock()
def producerFunction():
'''如果投的筛子比0.2大,则向盘子中增加一个苹果'''
global lock,dish
while True:
if(random.random() > 0.1):
lock.acquire()
if dish < 100:
dish+=1
print('生产者增加了一个苹果,现在有%d个苹果'%(dish,))
lock.release()
time.sleep(random.random()*3) def consumerFunction():
'''如果投的筛子比0.5大,则从盘子中取一个苹果'''
global lock,dish
while True:
if(random.random() > 0.9):
lock.acquire()
if dish > 0:
dish-=1
print('消费者拿走一个苹果现,在有%d个苹果'%(dish,))
lock.release()
time.sleep(random.random()*3) def begin():
ident1=_thread.start_new_thread(producerFunction,())
ident2=_thread.start_new_thread(consumerFunction,())
if __name__ == '__main__':
begin()
另一个较高级的锁为RLock锁,RLock对象内部维护着一个Lock对象,它是一种可重入的对象。对于Lock对象而言,如果一个线程连续两次进行acquire操作,那么由于第一次acquire之后没有release,第二次acquire将挂起线程。这会导致Lock对象永远不会release,使得线程死锁。RLock对象允许一个线程多次对其进行acquire操作,因为在其内部通过一个counter变量维护着线程acquire的次数。而且每一次的acquire操作必须有一个release操作与之对应,在所有的release操作完成之后,别的线程才能申请该RLock对象。
threading模块对Lock也提供和封装,提供了更高级的同步方式(可以理解为更高级的锁),包括threading.Event和threading.Condition,其中threading.Event为提供了简单的同步方式:一个进程标记event,其他进程等待,只需下面的几个方法即可:
Event.wait([timeout]) |
堵塞线程,直到Event对象内部标识位被设为True或超时(如果提供了参数timeout)。 |
Event.set() |
将标识号设为Ture |
Event.clear() |
设为标识符False |
threading.Condition 可以把Condiftion理解为一把高级的琐,它提供了比Lock, RLock更高级的功能,允许我们能够控制复杂的线程同步问题。threadiong.Condition在内部维护一个琐对象(默认是RLock),可以在创建Condigtion对象的时候把琐对象作为参数传入。Condition也提供了acquire, release方法,其含义与琐的acquire, release方法一致,其实它只是简单的调用内部琐对象的对应的方法而已。Condition还提供了如下方法(特别要注意:这些方法只有在占用琐(acquire)之后才能调用,否则将会报RuntimeError异常。):
Condition.wait([timeout]): |
wait方法释放内部所占用的琐,同时线程被挂起,直至接收到通知被唤醒或超时(如果提供了timeout参数的话)。当线程被唤醒并重新占有琐的时候,程序才会继续执行下去。 |
Condition.notify(): |
唤醒一个挂起的线程(如果存在挂起的线程)。注意:notify()方法不会释放所占用的琐。 |
Condition.notify_all() |
唤醒所有挂起的线程(如果存在挂起的线程)。注意:这些方法不会释放所占用的琐。 |
更多:
http://www.freeloong.net/20130623745.html
http://www.ibm.com/developerworks/cn/aix/library/au-threadingpython/
http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html 很好的文章
python _thread模块使用的更多相关文章
- python的_thread模块来实现多线程(<python核心编程例子>)
python中_thread模块是一个低级别的多线程模块,它的问题在于主线程运行完毕后,会立马把子线程给结束掉,不加处理地使用_thread模块是不合适的.这里把书中讲述的有关_thread使用的例子 ...
- python 多线程编程之_thread模块
参考书籍:python核心编程 _thread模块除了可以派生线程外,还提供了基本的同步数据结构,又称为锁对象(lock object,也叫原语锁.简单锁.互斥锁.互斥和二进制信号量). 下面是常用的 ...
- python多线程与_thread模块
进程与线程 1.进程:计算机程序只是存储在磁盘中的可执行二进制(或其他类型)的文件.只有把他们加载到内存中并被操作系统调用,才具有其生命周期.进程则是一个执行中的程序.每个进程都拥有自己的地址空间,内 ...
- Day05 - Python 常用模块
1. 模块简介 模块就是一个保存了 Python 代码的文件.模块能定义函数,类和变量.模块里也能包含可执行的代码. 模块也是 Python 对象,具有随机的名字属性用来绑定或引用. 下例是个简单的模 ...
- python高级-模块(14)
一.python中的模块 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt函数,必须用语句#include <math.h>引入math.h这个头文件,否则是无法正常进行调用的. ...
- python sys模块使用详情
python常用模块目录 sys模块提供了一系列有关Python运行环境的变量和函数.1.sys.argv可以用sys.argv获取当前正在执行的命令行参数的参数列表(list).变量解释sys.ar ...
- 罗列Python标准模块
文本 1. string:通用字符串操作 2. re:正则表达式操作 3. difflib:差异计算工具 4. textwrap:文本填充 5. unicodedata:Unicode字符数据库 6. ...
- Python标准模块--threading
1 模块简介 threading模块在Python1.5.2中首次引入,是低级thread模块的一个增强版.threading模块让线程使用起来更加容易,允许程序同一时间运行多个操作. 不过请注意,P ...
- Python的模块引用和查找路径
模块间相互独立相互引用是任何一种编程语言的基础能力.对于“模块”这个词在各种编程语言中或许是不同的,但我们可以简单认为一个程序文件是一个模块,文件里包含了类或者方法的定义.对于编译型的语言,比如C#中 ...
随机推荐
- 两种解决Qt5显示中文乱码的方法(使用QStringLiteral和#pragma execution_character_set("utf-8")两种方法)
升级到Qt5.X之后,原先解决的Qt显示中文乱码的方法突然不适用了,找了很多方式来解决这个问题第一种:在公司代码里看到的方法,先将对应的cpp文件用windows自带的记事本打开,另存为UTF-8格式 ...
- 文件的哈希值不在指定的目录文件中。此文件可能已损坏或被篡(Windows10 /Windows8.1)
------------------------------------------Windows10------------------------------------------------ ...
- Azure 网站的新增功能:可配置的环境变量
编辑人员注释:本文章由 WindowsAzure 网站团队的项目经理Erez Benari撰写. Azure最常用的强大功能之一是 XML文档转换 (XDT),通过此功能,您可以在Windows ...
- 基于Visual C++2013拆解世界五百强面试题--题12-进制转换
编程实现,把十进制数(long型)分别以二进制和十六进制形式输出,不能使用printf系列库函数. 转换成二进制,直接循环移位依次取每一位,判断1或0然后将相应字符放入字符串缓冲区中. 对于十六进制, ...
- 20140603 对error.c 用于分析源代码
20140603 对error.c 用于分析源代码 继续看error.c该功能 买家现在将自己的代码和数据汇编例如,下面的: 1.#include <stdio.h> 2 #inc ...
- 如何自定义iOS中的控件
本文译自 How to build a custom control in iOS .大家要是有什么问题,可以直接在 twitter 上联系原作者,当然也可以在最后的评论中回复我. 在开发过程中,有时 ...
- 自动分组+合并完整的sql脚本
BEGIN#前提:指定字符串长度为8字符定长#逻辑:循环8次,比对2个字符串相同索引位置下的数值大小,并取结果最大值.#示例:merge1(输入参数source1,输入参数source2,输出结果re ...
- md5 加密 swfit版
在swift工程中随便建一个objective-c类,会提示你生成一个Bridging-Header,点YES,然后删除刚才建立的objective-c类,只留下[工程名]-Bridging-Head ...
- js中去除换行(\r\n)
解决方法:replace(/\r\n/g,"").replace("\n","") 测试: <script> var str = ...
- 漏网之鱼--HTML&CSS
一.HTML <meta>标签使用该标签描述网页的具体摘要信息,包括文档内容类型,字符编码信息,搜索关键字,网站提供的功能和服务的详细描述等.<meta>标签描述的内容并不显示 ...