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 循环遍历字典元素的简单方法
Sep 11 Python
python使用两种发邮件的方式smtp和outlook示例
Jun 02 Python
pytorch构建网络模型的4种方法
Apr 13 Python
Python 实现一行输入多个值的方法
Apr 21 Python
python利用thrift服务读取hbase数据的方法
Dec 27 Python
Python基础之函数的定义与使用示例
Mar 23 Python
详解pytorch 0.4.0迁移指南
Jun 16 Python
win8.1安装Python 2.7版环境图文详解
Jul 01 Python
django echarts饼图数据动态加载的实例
Aug 12 Python
浅谈python元素如何去重,去重后如何保持原来元素的顺序不变
Feb 28 Python
python 两个一样的字符串用==结果为false问题的解决
Mar 12 Python
python Zmail模块简介与使用示例
Dec 19 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下使用curl模拟用户登陆的代码
2010/09/10 PHP
PHP fgetcsv 定义和用法(附windows与linux下兼容问题)
2012/05/29 PHP
js限制checkbox勾选的个数以及php获取多个checkbbox的方法深入解析
2013/07/18 PHP
php结合ajax实现手机发红包的案例
2016/10/13 PHP
网页中实现浏览器的最大,最小化和关闭按钮
2007/03/12 Javascript
获取HTML DOM节点元素的方法的总结
2009/08/21 Javascript
jquery实现的鼠标拖动排序Li或Table
2014/05/04 Javascript
表单验证插件Validation应用的实例讲解
2015/10/10 Javascript
修改Jquery Dialog 位置的实现方法
2016/08/26 Javascript
js html css实现复选框全选与反选
2016/10/09 Javascript
bootstrap手风琴折叠示例代码分享
2017/05/22 Javascript
vue jsx 使用指南及vue.js 使用jsx语法的方法
2017/11/11 Javascript
JS实现不用中间变量temp 实现两个变量值得交换方法
2018/02/04 Javascript
JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】
2019/02/22 Javascript
js实现数字从零慢慢增加到指定数字示例
2019/11/07 Javascript
JS实现横向轮播图(中级版)
2020/01/18 Javascript
vue如何实现动态加载脚本
2020/02/05 Javascript
TypeScript 引用资源文件后提示找不到的异常处理技巧
2020/07/15 Javascript
Angular利用HTTP POST下载流文件的步骤记录
2020/07/26 Javascript
[01:19:46]DOTA2-DPC中国联赛 正赛 SAG vs DLG BO3 第一场 2月28日
2021/03/11 DOTA
python 运算符 供重载参考
2009/06/11 Python
python复制文件的方法实例详解
2015/05/22 Python
使用简单工厂模式来进行Python的设计模式编程
2016/03/01 Python
Django后台获取前端post上传的文件方法
2018/05/28 Python
在Pycharm中执行scrapy命令的方法
2019/01/16 Python
使用Python3+PyQT5+Pyserial 实现简单的串口工具方法
2019/02/13 Python
Python后台开发Django会话控制的实现
2019/04/15 Python
解决pyinstaller打包发布后的exe文件打开控制台闪退的问题
2019/06/21 Python
Django多数据库的实现过程详解
2019/08/01 Python
python numpy--数组的组合和分割实例
2020/02/24 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
2020/06/28 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
2020/07/03 Python
HTML5 Canvas实现烟花绽放特效
2016/03/02 HTML / CSS
优秀驾驶员先进事迹材料
2014/05/04 职场文书
处级干部考察材料
2014/12/24 职场文书
奖学金感谢信
2015/01/21 职场文书