Python模块学习: thread 多线程处理
2015-06-15 08:58
405 查看
http://blog.csdn.net/jgood/article/details/4299476
这段时间一直在用 Python 写一个游戏的服务器程序。在编写过程中,不可避免的要用多线程来处理与客户端的交互。 Python 标准库提供了 thread 和 threading 两个模块来对多线程进行支持。其中, thread 模块以低级、原始的方式来处理和控制线程,而 threading 模块通过对 thread 进行二次封装,提供了更方便的 api 来处理线程。 虽然使用 thread 没有 threading 来的方便,但它更灵活。今天先介绍 thread 模块的基本使用,下一篇 将介绍threading 模块。
在介绍 thread 之前,先看一段代码,猜猜程序运行完成之后,在控制台上输出的结果是什么?
[python] view plaincopy
#coding=gbk
import thread, time, random
count = 0
def threadTest():
global count
for i in xrange(10000):
count += 1
for i in range(10):
thread.start_new_thread(threadTest, ()) #如果对start_new_thread函数不是很了解,不要着急,马上就会讲解
time.sleep(3)
print count #count是多少呢?是10000 * 10 吗?
[python] view plaincopy
#coding=gbk
import thread, time
def threadFunc(a = None, b = None, c = None, d = None):
print time.strftime('%H:%M:%S', time.localtime()), a
time.sleep(1)
print time.strftime('%H:%M:%S', time.localtime()), b
time.sleep(1)
print time.strftime('%H:%M:%S', time.localtime()), c
time.sleep(1)
print time.strftime('%H:%M:%S', time.localtime()), d
time.sleep(1)
print time.strftime('%H:%M:%S', time.localtime()), 'over'
thread.start_new_thread(threadFunc, (3, 4, 5, 6)) #创建线程,并执行threadFunc函数。
time.sleep(5)
[python] view plaincopy
import thread, time
thread.start_new_thread(lambda : (thread.interrupt_main(), ), ())
try:
time.sleep(2)
except KeyboardInterrupt, e:
print 'error:', e
print 'over'
下面介绍 thread 模块中的琐,琐可以保证在任何时刻,最多只有一个线程可以访问共享资源。
thread.LockType 是 thread 模块中定义的琐类型。它有如下方法:
现在我们回过头来看文章开始处给出的那段代码:代码中定义了一个函数 threadTest ,它将全局变量逐一的增加 10000 ,然后在主线程中开启了 10 个子线程来调用 threadTest 函数。但结果并不是预料中的 10000 * 10 ,原因主要是对 count 的并发操作引来的。全局变量 count 是共享资源,对它的操作应该串行的进行。下面对那段代码进行修改,在对 count 操作的时候,进行加琐处理。看看程序运行的结果是否和预期一致。修改后的代码:
[python] view plaincopy
#coding=gbk
import thread, time, random
count = 0
lock = thread.allocate_lock() #创建一个琐对象
def threadTest():
global count, lock
lock.acquire() #获取琐
for i in xrange(10000):
count += 1
lock.release() #释放琐
for i in xrange(10):
thread.start_new_thread(threadTest, ())
time.sleep(3)
print count
thread模块是不是并没有想像中的那么难!简单就是美,这就是Python。更多关于thread模块的内容,请参考Python手册 thread 模块
这段时间一直在用 Python 写一个游戏的服务器程序。在编写过程中,不可避免的要用多线程来处理与客户端的交互。 Python 标准库提供了 thread 和 threading 两个模块来对多线程进行支持。其中, thread 模块以低级、原始的方式来处理和控制线程,而 threading 模块通过对 thread 进行二次封装,提供了更方便的 api 来处理线程。 虽然使用 thread 没有 threading 来的方便,但它更灵活。今天先介绍 thread 模块的基本使用,下一篇 将介绍threading 模块。
在介绍 thread 之前,先看一段代码,猜猜程序运行完成之后,在控制台上输出的结果是什么?
[python] view plaincopy
#coding=gbk
import thread, time, random
count = 0
def threadTest():
global count
for i in xrange(10000):
count += 1
for i in range(10):
thread.start_new_thread(threadTest, ()) #如果对start_new_thread函数不是很了解,不要着急,马上就会讲解
time.sleep(3)
print count #count是多少呢?是10000 * 10 吗?
thread.start_new_thread ( function , args [ , kwargs ] )
函数将创建一个新的线程,并返回该线程的标识符(标识符为整数)。参数 function 表示线程创建之后,立即执行的函数,参数 args 是该函数的参数,它是一个元组类型;第二个参数 kwargs 是可选的,它为函数提供了命名参数字典。函数执行完毕之后,线程将自动退出。如果函数在执行过程中遇到未处理的异常,该线程将退出,但不会影响其他线程的执行。 下面是一个简单的例子:[python] view plaincopy
#coding=gbk
import thread, time
def threadFunc(a = None, b = None, c = None, d = None):
print time.strftime('%H:%M:%S', time.localtime()), a
time.sleep(1)
print time.strftime('%H:%M:%S', time.localtime()), b
time.sleep(1)
print time.strftime('%H:%M:%S', time.localtime()), c
time.sleep(1)
print time.strftime('%H:%M:%S', time.localtime()), d
time.sleep(1)
print time.strftime('%H:%M:%S', time.localtime()), 'over'
thread.start_new_thread(threadFunc, (3, 4, 5, 6)) #创建线程,并执行threadFunc函数。
time.sleep(5)
thread.exit ()
结束当前线程。调用该函数会触发 SystemExit 异常,如果没有处理该异常,线程将结束。thread.get_ident ()
返回当前线程的标识符,标识符是一个非零整数。thread.interrupt_main ()
在主线程中触发 KeyboardInterrupt 异常。子线程可以使用该方法来中断主线程。下面的例子演示了在子线程中调用 interrupt_main ,在主线程中捕获异常 :[python] view plaincopy
import thread, time
thread.start_new_thread(lambda : (thread.interrupt_main(), ), ())
try:
time.sleep(2)
except KeyboardInterrupt, e:
print 'error:', e
print 'over'
下面介绍 thread 模块中的琐,琐可以保证在任何时刻,最多只有一个线程可以访问共享资源。
thread.LockType 是 thread 模块中定义的琐类型。它有如下方法:
lock.acquire ( [ waitflag ] )
获取琐。函数返回一个布尔值,如果获取成功,返回 True ,否则返回 False 。参数 waitflag 的默认值是一个非零整数,表示如果琐已经被其他线程占用,那么当前线程将一直等待,只到其他线程释放,然后获取访琐。如果将参数 waitflag 置为 0 ,那么当前线程会尝试获取琐,不管琐是否被其他线程占用,当前线程都不会等待。lock.release ()
释放所占用的琐。lock.locked ()
判断琐是否被占用。现在我们回过头来看文章开始处给出的那段代码:代码中定义了一个函数 threadTest ,它将全局变量逐一的增加 10000 ,然后在主线程中开启了 10 个子线程来调用 threadTest 函数。但结果并不是预料中的 10000 * 10 ,原因主要是对 count 的并发操作引来的。全局变量 count 是共享资源,对它的操作应该串行的进行。下面对那段代码进行修改,在对 count 操作的时候,进行加琐处理。看看程序运行的结果是否和预期一致。修改后的代码:
[python] view plaincopy
#coding=gbk
import thread, time, random
count = 0
lock = thread.allocate_lock() #创建一个琐对象
def threadTest():
global count, lock
lock.acquire() #获取琐
for i in xrange(10000):
count += 1
lock.release() #释放琐
for i in xrange(10):
thread.start_new_thread(threadTest, ())
time.sleep(3)
print count
thread模块是不是并没有想像中的那么难!简单就是美,这就是Python。更多关于thread模块的内容,请参考Python手册 thread 模块
相关文章推荐
- python字符串编码识别模块chardet简单应用
- Python字符串格式化
- 在Ubuntu 14.04 64bit上安装python-pyqt5软件包(python 2.7)
- python控制台输入密码
- 关于Python的属性、参数、方法的解释、区别
- python 装饰器
- Python之第一个程序
- 一些数字音频的基础定义
- Python字符串格式化
- python字符串编码识别模块chardet简单应用
- 深入理解Python中各种方法的运作原理
- python实现批量下载新浪博客的方法
- python获取mp3文件信息的方法
- Python中文字符串截取问题
- 构建Python包的五个简单准则简介
- Python实现简单截取中文字符串的方法
- Python中datetime常用时间处理方法
- python简单实现基于SSL的IRC bot实例
- Python从MP3文件获取id3的方法
- Python修改MP3文件的方法