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缩进区别分析
Feb 15 Python
Python中使用HTMLParser解析html实例
Feb 08 Python
python通过floor函数舍弃小数位的方法
Mar 17 Python
Python中import导入上一级目录模块及循环import问题的解决
Jun 04 Python
python Django中models进行模糊查询的示例
Jul 18 Python
Python Subprocess模块原理及实例
Aug 26 Python
详解Python 中sys.stdin.readline()的用法
Sep 12 Python
Django 再谈一谈json序列化
Mar 16 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
Feb 07 Python
python爬虫利用代理池更换IP的方法步骤
Feb 21 Python
python基础之爬虫入门
May 10 Python
Python使用OpenCV实现虚拟缩放效果
Feb 28 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
php ci框架验证码实例分析
2013/06/26 PHP
php制作简单模版引擎
2016/04/07 PHP
php5.3后静态绑定用法详解
2016/11/11 PHP
PHP unset函数原理及使用方法解析
2020/08/14 PHP
js右键菜单效果代码
2007/07/21 Javascript
效率高的Javscript字符串替换函数的benchmark
2008/08/02 Javascript
JavaScript Timer实现代码
2010/02/17 Javascript
JavaScipt中的Math.ceil() 、Math.floor() 、Math.round() 三个函数的理解
2010/04/29 Javascript
jquery png 透明解决方案(推荐)
2010/08/21 Javascript
JavaScript设计模式之观察者模式(发布者-订阅者模式)
2014/09/24 Javascript
JavaScript设计模式之建造者模式介绍
2014/12/28 Javascript
JS实现最简单的冒泡排序算法
2017/02/15 Javascript
微信小程序手势操作之单触摸点与多触摸点
2017/03/10 Javascript
详解使用JS如何制作简单的ASCII图与单极图
2017/03/31 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
2017/06/08 jQuery
vue项目中用cdn优化的方法
2018/01/03 Javascript
微信jssdk逻辑在vue中的运用详解
2018/11/14 Javascript
vue.js click点击事件获取当前元素对象的操作
2020/08/07 Javascript
ES6中的Javascript解构的实现
2020/10/30 Javascript
vue 页面跳转的实现方式
2021/01/12 Vue.js
python中查找excel某一列的重复数据 剔除之后打印
2013/02/10 Python
Python内置的HTTP协议服务器SimpleHTTPServer使用指南
2016/03/30 Python
Python删除Java源文件中全部注释的实现方法
2017/08/30 Python
scrapy爬虫完整实例
2018/01/25 Python
Python格式化输出%s和%d
2018/05/07 Python
Python面向对象类继承和组合实例分析
2018/05/28 Python
Python DataFrame设置/更改列表字段/元素类型的方法
2018/06/09 Python
在python3.9下如何安装scrapy的方法
2021/02/03 Python
东南亚地区最大的购物网站Lazada新加坡站点:Lazada.sg
2016/07/17 全球购物
Java Servlet API中forward() 与redirect()的区别
2014/04/20 面试题
公务员的自我鉴定
2013/10/26 职场文书
小学教师自我鉴定
2013/11/07 职场文书
会议接待欢迎词
2014/01/12 职场文书
迎国庆演讲稿
2014/09/05 职场文书
2014小学生国庆65周年演讲稿
2014/09/21 职场文书
演讲稿之感恩老师(三篇范文)
2019/09/06 职场文书