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 datetime时间格式化去掉前导0
Jul 31 Python
python使用wxPython打开并播放wav文件的方法
Apr 24 Python
深入浅析Python中list的复制及深拷贝与浅拷贝
Sep 03 Python
python 用所有标点符号分隔句子的示例
Jul 15 Python
tensorflow获取预训练模型某层参数并赋值到当前网络指定层方式
Jan 24 Python
Django 设置多环境配置文件载入问题
Feb 25 Python
Windows下Anaconda和PyCharm的安装与使用详解
Apr 23 Python
python 解决selenium 中的 .clear()方法失效问题
Sep 01 Python
Python实例方法、类方法、静态方法区别详解
Sep 05 Python
python向xls写入数据(包括合并,边框,对齐,列宽)
Feb 02 Python
python单例模式的应用场景实例讲解
Feb 24 Python
python中__slots__节约内存的具体做法
Jul 04 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
虹吸式咖啡壶操作
2021/03/03 冲泡冲煮
PHP版国家代码、缩写查询函数代码
2011/08/14 PHP
php smarty截取中文字符乱码问题?gb2312/utf-8
2011/11/07 PHP
解析coreseek for sphinx的使用
2013/06/21 PHP
php中json_encode UTF-8中文乱码的更好解决方法
2014/09/28 PHP
PHP多线程之内部多线程实例分析
2015/03/09 PHP
php根据一个给定范围和步进生成数组的方法
2015/06/19 PHP
PHP实现的操作数组类库定义与用法示例
2019/05/24 PHP
PHP dirname(__FILE__)原理及用法解析
2020/10/28 PHP
js中top、clientTop、scrollTop、offsetTop的区别 文字详细说明版
2011/01/08 Javascript
jquery更换文章内容与改变字体大小代码
2013/09/30 Javascript
JavaScript对象学习经验整理
2013/10/12 Javascript
JS操作Cookies的小例子
2013/10/15 Javascript
简单选项卡 js和jquery制作方法分享
2014/02/26 Javascript
jQuery通过点击行来删除HTML表格行的实现示例
2014/09/10 Javascript
javascript中substring()、substr()、slice()的区别
2015/08/30 Javascript
jQuery+jsp下拉框联动获取本地数据的方法(附源码)
2015/12/03 Javascript
卸载安装Node.js与npm过程详解
2016/08/15 Javascript
jquery购物车结算功能实现方法
2020/10/29 Javascript
详解angularJs指令的3种绑定策略
2017/04/13 Javascript
VUE axios发送跨域请求需要注意的问题
2017/07/06 Javascript
node.js基于dgram数据报模块创建UDP服务器和客户端操作示例
2020/02/12 Javascript
jQuery实现的分页插件完整示例
2020/05/26 jQuery
vuex页面刷新导致数据丢失的解决方案
2020/12/10 Vue.js
Python实现随机漫步功能
2018/07/09 Python
浅谈dataframe中更改列属性的方法
2018/07/10 Python
python2和python3的输入和输出区别介绍
2018/11/20 Python
scrapy结合selenium解析动态页面的实现
2020/09/28 Python
介绍一下ICMP(Internet Control Message Protocol)Internet控制信息协议
2016/11/26 面试题
Linux开机引导的步骤是什么
2015/10/19 面试题
教师党员批评与自我批评发言稿
2014/10/15 职场文书
2014年学生管理工作总结
2014/12/20 职场文书
食堂采购员岗位职责
2015/04/03 职场文书
叶问观后感
2015/06/15 职场文书
幼儿园老师新年寄语
2015/08/17 职场文书
LeetCode189轮转数组python示例
2022/08/05 Python