Python 多线程的实例详解


Posted in Python onSeptember 07, 2017

 Python 多线程的实例详解

一)线程基础

1、创建线程:

thread模块提供了start_new_thread函数,用以创建线程。start_new_thread函数成功创建后还可以对其进行操作。
其函数原型:

start_new_thread(function,atgs[,kwargs])

其参数含义如下:

    function: 在线程中执行的函数名
    args:元组形式的参数列表。
    kwargs: 可选参数,以字典的形式指定参数

方法一:通过使用thread模块中的函数创建新线程。

>>> import thread 
>>> def run(n): 
  for i in range(n): 
    print i 
 
     
>>> thread.start_new_thread(run,(4,))  #注意第二个参数一定要是元组的形式 
53840 
 
 
1 
>>>  
2 
3 
KeyboardInterrupt 
>>> thread.start_new_thread(run,(2,)) 
17840 
 
 
1 
>>>  
thread.start_new_thread(run,(),{'n':4}) 
39720 
 
 
1 
>>>  
2 
3 
thread.start_new_thread(run,(),{'n':3}) 
32480 
 
 
1 
>>>  
2

方法二:通过继承threading.Thread创建线程

>>> import threading 
>>> class mythread(threading.Thread): 
  def __init__(self,num): 
    threading.Thread.__init__(self) 
    self.num = num 
  def run(self):        #重载run方法 
    print 'I am', self.num 
 
     
>>> t1 = mythread(1) 
>>> t2 = mythread(2) 
>>> t3 = mythread(3) 
>>> t1.start()      #运行线程t1 
I am 
>>> 1 
t2.start() 
I am 
>>> 2 
t3.start() 
I am 
>>> 3

方法三:使用threading.Thread直接在线程中运行函数。

import threading 
>>> def run(x,y): 
  for i in range(x,y): 
    print i 
 
>>> t1 = threading.Thread(target=run,args=(15,20)) #直接使用Thread附加函数args为函数参数 
 
>>> t1.start() 
15 
>>>  
16 
17 
18 
19

二)Thread对象中的常用方法:

1、isAlive方法:

>>> import threading 
>>> import time 
>>> class mythread(threading.Thread): 
  def __init__(self,id): 
    threading.Thread.__init__(self) 
    self.id = id 
  def run(self): 
    time.sleep(5)  #休眠5秒 
    print self.id 
 
     
>>> t = mythread(1) 
>>> def func(): 
  t.start() 
  print t.isAlive()  #打印线程状态 
 
   
>>> func() 
True 
>>> 1

2、join方法:

原型:join([timeout]) 

    timeout: 可选参数,线程运行的最长时间

import threading 
>>> import time   #导入time模块 
>>> class Mythread(threading.Thread): 
  def __init__(self,id): 
    threading.Thread.__init__(self) 
    self.id = id 
  def run(self): 
    x = 0 
    time.sleep(20) 
    print self.id 
 
     
>>> def func(): 
  t.start() 
  for i in range(5): 
    print i 
 
     
>>> t = Mythread(2) 
>>> func() 
0 
1 
2 
3 
4 
>>> 2 
def func(): 
  t.start() 
  t.join() 
  for i in range(5): 
    print i 
 
     
>>> t = Mythread(3) 
>>> func() 
3 
0 
1 
2 
3 
4 
>>>

3、线程名:

>>> import threading 
>>> class mythread(threading.Thread): 
  def __init__(self,threadname): 
    threading.Thread.__init__(self,name=threadname) 
  def run(self): 
    print self.getName() 
 
     
>>>  
>>> t1 = mythread('t1') 
>>> t1.start() 
t1 
>>>

 4、setDaemon方法

在脚本运行的过程中有一个主线程,如果主线程又创建了一个子线程,那么当主线程退出时,会检验子线程是否完成。如果子线程未完成,则主线程会在等待子线程完成后退出。

当需要主线程退出时,不管子线程是否完成都随主线程退出,则可以使用Thread对象的setDaemon方法来设置。 

三)线程同步

1.简单的线程同步

使用Thread对象的Lock和RLock可以实现简单的线程同步。对于如果需要每次只有一个线程操作的数据,可以将操作过程放在acquire方法和release方法之间。如: 

# -*- coding:utf-8 -*- 
import threading 
import time 
class mythread(threading.Thread): 
  def __init__(self,threadname): 
    threading.Thread.__init__(self,name = threadname) 
  def run(self): 
    global x        #设置全局变量 
#    lock.acquire()     #调用lock的acquire方法 
    for i in range(3): 
      x = x + 1 
    time.sleep(2) 
    print x 
#    lock.release()     #调用lock的release方法 
#lock = threading.RLock()    #生成Rlock对象 
t1 = [] 
for i in range(10): 
  t = mythread(str(i)) 
  t1.append(t) 
x = 0          #将全局变量的值设为0 
for i in t1:  
  i.start() 
 
E:/study/<a href="http://lib.csdn.net/base/python" rel="external nofollow" class='replace_word' title="Python知识库" target='_blank' style='color:#df3434; font-weight:bold;'>Python</a>/workspace>xianchengtongbu.py 
3 
6 
9 
12 
15 
18 
21 
24 
27 
30

如果将lock.acquire()和lock.release(),lock = threading.Lock()删除后保存运行脚本,结果将是输出10个30。30是x的最终值,由于x是全局变量,每个线程对其操作后进入休眠状态,在线程休眠的时候,Python解释器就执行了其他的线程而是x的值增加。当所有线程休眠结束后,x的值已被所有线修改为了30,因此输出全部为30。 

2、使用条件变量保持线程同步。

python的Condition对象提供了对复制线程同步的支持。使用Condition对象可以在某些事件触发后才处理数据。Condition对象除了具有acquire方法和release的方法外,还有wait方法、notify方法、notifyAll方法等用于条件处理。

# -*- coding:utf-8 -*- 
import threading 
class Producer(threading.Thread): 
  def __init__(self,threadname): 
    threading.Thread.__init__(self,name = threadname) 
  def run(self): 
    global x 
    con.acquire() 
    if x == 1000000: 
      con.wait() 
    #  pass 
    else: 
      for i in range(1000000): 
        x = x + 1 
      con.notify() 
    print x 
    con.release() 
class Consumer(threading.Thread): 
  def __init__(self,threadname): 
    threading.Thread.__init__(self,name = threadname) 
  def run(self): 
    global x  
    con.acquire() 
    if x == 0: 
      con.wait() 
      #pass 
    else: 
      for i in range(1000000): 
        x = x - 1 
      con.notify() 
    print x  
    con.release() 
con = threading.Condition() 
x = 0 
p = Producer('Producer') 
c = Consumer('Consumer') 
p.start() 
c.start() 
p.join() 
c.join() 
print x 
 
E:/study/python/workspace>xianchengtongbu2.py 
1000000 
0 
0

线程间通信:

Event对象用于线程间的相互通信。他提供了设置信号、清除信宏、等待等用于实现线程间的通信。

1、设置信号。Event对象使用了set()方法后,isSet()方法返回真。
2、清除信号。使用Event对象的clear()方法后,isSet()方法返回为假。
3、等待。当Event对象的内部信号标志为假时,则wait()方法一直等到其为真时才返回。还可以向wait传递参数,设定最长的等待时间。

# -*- coding:utf-8 -*- 
import threading 
class mythread(threading.Thread): 
  def __init__(self,threadname): 
    threading.Thread.__init__(self,name = threadname) 
  def run(self): 
    global event 
    if event.isSet(): 
      event.clear() 
      event.wait()  #当event被标记时才返回 
      print self.getName() 
    else: 
      print self.getName() 
      event.set() 
event = threading.Event() 
event.set() 
t1 = [] 
for i in range(10): 
  t = mythread(str(i)) 
  t1.append(t) 
for i in t1: 
  i.start()

如有疑问请留言或者到本站社区交流讨论,感谢 阅读,希望能帮助到大家,谢谢大家对本站的支持!

Python 相关文章推荐
Python实现求最大公约数及判断素数的方法
May 26 Python
利用Python自动监控网站并发送邮件告警的方法
Aug 24 Python
使用Python写一个贪吃蛇游戏实例代码
Aug 21 Python
Python语言生成水仙花数代码示例
Dec 18 Python
Python爬虫常用小技巧之设置代理IP
Sep 13 Python
PyQt4编程之让状态栏显示信息的方法
Jun 18 Python
简单了解python单例模式的几种写法
Jul 01 Python
Python 实现数组相减示例
Dec 27 Python
Python爬虫实例——爬取美团美食数据
Jul 15 Python
scrapy利用selenium爬取豆瓣阅读的全步骤
Sep 20 Python
正确的理解和使用Django信号(Signals)
Apr 14 Python
让文件路径提取变得更简单的Python Path库
May 27 Python
Python 闭包的使用方法
Sep 07 #Python
Python基于回溯法子集树模板解决选排问题示例
Sep 07 #Python
Python基于回溯法子集树模板解决全排列问题示例
Sep 07 #Python
python中利用await关键字如何等待Future对象完成详解
Sep 07 #Python
Python基于回溯法子集树模板解决m着色问题示例
Sep 07 #Python
python中利用Future对象异步返回结果示例代码
Sep 07 #Python
python中利用Future对象回调别的函数示例代码
Sep 07 #Python
You might like
wordpress自定义url参数实现路由功能的代码示例
2013/11/28 PHP
PHP里8个鲜为人知的安全函数分析
2014/12/09 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
PHP如何将图片文件上传到另外一台服务器上
2019/08/26 PHP
传智播客学习之JavaScript基础篇
2009/11/13 Javascript
window.ActiveXObject使用说明
2010/11/08 Javascript
jquery scrollTop方法根据滚动像素显示隐藏顶部导航条
2013/05/27 Javascript
JS判断元素是否在数组内的实现代码
2016/03/30 Javascript
vue小图标favicon不显示的解决方案
2017/09/19 Javascript
Vue 项目部署到服务器的问题解决方法
2017/12/05 Javascript
详解webpack与SPA实践之开发环境搭建
2017/12/18 Javascript
利用nginx + node在阿里云部署https的步骤详解
2017/12/19 Javascript
vue.js实现二级菜单效果
2019/10/19 Javascript
微信小程序在text文本实现多种字体样式
2019/11/08 Javascript
jQuery实现朋友圈查看图片
2020/09/11 jQuery
Python爬取APP下载链接的实现方法
2016/09/30 Python
python实现读取并显示图片的两种方法
2017/01/13 Python
Python随机数用法实例详解【基于random模块】
2017/04/18 Python
浅析Python中return和finally共同挖的坑
2017/08/18 Python
Python数据结构与算法之图的广度优先与深度优先搜索算法示例
2017/12/14 Python
python中将正则过滤的内容输出写入到文件中的实例
2018/10/21 Python
Python input函数使用实例解析
2019/11/22 Python
Python实现aes加密解密多种方法解析
2020/05/15 Python
Python Django form 组件动态从数据库取choices数据实例
2020/05/19 Python
用 Django 开发一个 Python Web API的方法步骤
2020/12/03 Python
教你一分钟在win10终端成功安装Pytorch的方法步骤
2021/01/28 Python
CSS3+DIV实现漂亮的动画彩色标签
2016/06/16 HTML / CSS
使用 css3 实现圆形进度条的示例
2017/07/05 HTML / CSS
韩国三大免税店之一:THE GRAND 中文免税店
2016/07/21 全球购物
The Hut德国站点:时装、家居用品、美容等
2016/09/23 全球购物
英国网上购买肉类网站:Great British Meat
2018/10/17 全球购物
毕业生个人求职的自我评价
2013/10/28 职场文书
党委干部批评与自我批评发言稿
2014/09/28 职场文书
小学三八妇女节活动总结
2015/02/06 职场文书
2015年学校德育工作总结
2015/04/22 职场文书
个人收入证明范本
2015/06/12 职场文书