简要讲解Python编程中线程的创建与锁的使用


Posted in Python onFebruary 28, 2016

创建线程
创建线程的两种方法:
1,直接调用threading.Thread来构造thread对象,Thread的参数如下:
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}) 
group为None;
target为线程将要执行的功能函数;
name为线程的名字,也可以在对象构造后调用setName()来设定;
args为tuple类型的参数,可以为多个,如果只有一个也的使用tuple的形式传入,例如(1,);
kwargs为dict类型的参数,也即位命名参数
threading.Thread对象的其他方法:
start(),用来启动线程;
join(), 等待直到线程结束;
isAlive(),获取线程状态

setDeamon(), 设置线程为deamon线程,必须在start()调用前调用,默认为非demon。
注意: python的主线程在没有非deamon线程存在时就会退出。

threading.currentthread() , 用来获得当前的线程;
threading.enumerate() , 用来多的当前存活的所有线程;

#coding:utf-8
import threading
def func1(num):
 for i in range(num):
  #threading.currentThread()获取当前线程,getName()获取线程名字
  print 'I am %s.num:%s' % (threading.currentThread().getName(), i)
      
def main(thread_num):
 thread_list = [] #定义一个线程列表
 for i in range(thread_num):
  thread_list.append(threading.Thread(target=func1, args = (3, )))
 for a in thread_list:
  #a.setDaemon(True)这个setDaemon默认为False 非守护线程
  #表示主线程等所有子线程结束后,在结束
  #设置为True的话 表示是个守护线程 子线程就会随着主线程的结束而结束
  #听说服务监控工具生成的心跳线程 就是用的守护线程
  a.start()
      
      
 for a in thread_list:
  a.join() #表示等待直到线程运行完毕
      
main(3)

运行结果

I am Thread-1.num:0
I am Thread-1.num:1
I am Thread-1.num:2
I am Thread-2.num:0
I am Thread-2.num:1
I am Thread-2.num:2
I am Thread-3.num:0
I am Thread-3.num:1
I am Thread-3.num:2

2,直接从threading.Thread继承,然后重写__init__方法和run方法

#coding:utf-8
import threading
class MyThread(threading.Thread): #继承父类threading.Thread
 def __init__(self, num ): 
  threading.Thread.__init__(self)
  self.num = num
   
 #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 
 def run(self):
  for i in range(self.num):
   print 'I am %s.num:%s' % (self.getName(), i)
     
for i in range(3):
 t = MyThread(3)
 t.start()
 t.join()

运行结果

I am Thread-1.num:0
I am Thread-1.num:1
I am Thread-1.num:2
I am Thread-2.num:0
I am Thread-2.num:1
I am Thread-2.num:2
I am Thread-3.num:0
I am Thread-3.num:1
I am Thread-3.num:2

锁的使用
假设我们有一个公共数据x(也可以叫共享资源,临界资源),然后跑10个线程都去访问这变量并对这个变量进行修改的操作,那么就得到意料之外的结果。

import threading       # 导入threading模块
import time        # 导入time模块
class mythread(threading.Thread):  # 通过继承创建类
 def __init__(self,threadname):  # 初始化方法
  # 调用父类的初始化方法
  threading.Thread.__init__(self,name = threadname) 
 def run(self):       # 重载run方法
  global x     # 使用global表明x为全局变量
  for i in range(3):
   x = x + 1
  time.sleep(2)   # 调用sleep函数,让线程休眠5秒
  print x
                
tl = []        # 定义列表
for i in range(10):
 t = mythread(str(i))    # 类实例化
 tl.append(t)      # 将类对象添加到列表中
               
x=0         # 将x赋值为0
for i in tl:
 i.start()       # 依次运行线程

                                                        
运行结果

[root@localhost ~]# python syn.py
30
30
30
30
30
30
30
30
30
30

由于x是全局变量(共享资源),每个线程对x操作后就休眠了
在线程休眠的时候其他线程也都开始执行操作,
最终休眠5秒后x的值最终就被修改为30了

使用互斥锁来保护公共资源。用互斥锁来保证同一时刻只有一个线程访问公共资源,实现简单的同步
互斥锁:threading.Lock 
互斥锁方法:acquire() 获取锁   release():释放锁
当有一个线程获的锁之后,这把锁就会进入locke状态(被锁起来了),另外的线程试图获取锁的时候就会变成同步阻塞状态,
当拥有线程锁的的线程调用锁方法 release()之后就会释放锁,那么锁就会变成开锁unlocked状态,之后再从同步阻塞状态的线程中选择一个来获得锁

import threading       # 导入threading模块
import time        # 导入time模块
class mythread(threading.Thread):     # 通过继承创建类
 def __init__(self,threadname):     # 初始化方法
  threading.Thread.__init__(self,name = threadname) 
 def run(self):       # 重载run方法
  global x      # 使用global表明x为全局变量
  lock.acquire()      # 调用lock的acquire方法
  for i in range(3):
   x = x + 1
  time.sleep(2)   # 调用sleep函数,让线程休眠5秒
  print x
  lock.release()    # 调用lock的release方法
lock = threading.Lock()    # 类实例化
tl = []       # 定义列表
for i in range(10):
 t = mythread(str(i))   # 类实例化
 tl.append(t)    # 将类对象添加到列表中
       
x=0      # 将x赋值为0
for i in tl:
 i.start()      # 依次运行线程

                          
运行结果:

[root@localhost ~]# python syn.py
3
6
9
12
15
18
21
24
27
30

可重入锁:threading.RLock()
方法和互斥锁一样。
假设一个锁嵌套的情况:有个线程以及获取到锁和共享资源了,但是又需要一把锁来获取另外一个资源,那么只要把代码里面的:

lock = threading.Lock()

修改为:

lock = threading.RLock()
Python 相关文章推荐
python2.7删除文件夹和删除文件代码实例
Dec 18 Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
Feb 23 Python
解决每次打开pycharm直接进入项目的问题
Oct 28 Python
python统计中文字符数量的两种方法
Jan 31 Python
Python按钮的响应事件详解
Mar 04 Python
python爬虫项目设置一个中断重连的程序的实现
Jul 26 Python
Python如何基于Tesseract实现识别文字功能
Jun 05 Python
pandas 像SQL一样使用WHERE IN查询条件说明
Jun 05 Python
详解python如何引用包package
Jun 07 Python
基于Tensorflow的MNIST手写数字识别分类
Jun 17 Python
在tensorflow实现直接读取网络的参数(weight and bias)的值
Jun 24 Python
python实现取余操作的简单实例
Aug 16 Python
Python中time模块和datetime模块的用法示例
Feb 28 #Python
python 写的一个爬虫程序源码
Feb 28 #Python
Python基础语法(Python基础知识点)
Feb 28 #Python
python中map()与zip()操作方法
Feb 27 #Python
python中input()与raw_input()的区别分析
Feb 27 #Python
python PIL模块与随机生成中文验证码
Feb 27 #Python
Pythont特殊语法filter,map,reduce,apply使用方法
Feb 27 #Python
You might like
一个php作的文本留言本的例子(六)
2006/10/09 PHP
PHP中判断变量为空的几种方法小结
2013/11/12 PHP
PHP整合七牛实现上传文件
2015/07/03 PHP
PHP模拟asp.net的StringBuilder类实现方法
2015/08/08 PHP
Thinkphp无限级分类代码
2015/11/11 PHP
Mac版PhpStorm之XAMPP整合apache服务器配置的图文教程详解
2016/10/13 PHP
jQuery 位置插件
2008/12/25 Javascript
JS验证控制输入中英文字节长度(input、textarea等)具体实例
2013/06/21 Javascript
js判断60秒以及倒计时示例代码
2014/01/24 Javascript
JavaScript实现列表分页功能特效
2015/05/15 Javascript
jQuery实现提示密码强度的代码
2015/07/15 Javascript
把json格式的字符串转换成javascript对象或数组的方法总结
2016/11/03 Javascript
JS实现二维数组横纵列转置的方法
2018/04/17 Javascript
JS实现快递单打印功能【推荐】
2018/06/21 Javascript
使用JQuery自动完成插件Auto Complete详解
2019/06/18 jQuery
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
2020/05/03 Javascript
基于aotu.js实现微信自动添加通讯录中的联系人功能
2020/05/28 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
Vue与React的区别和优势对比
2020/12/18 Vue.js
[03:00]2014DOTA2国际邀请赛 Titan淘汰潸然泪下Ohaiyo专访
2014/07/15 DOTA
wxPython中文教程入门实例
2014/06/09 Python
Python运算符重载用法实例分析
2015/06/01 Python
python机器学习库常用汇总
2017/11/15 Python
pandas表连接 索引上的合并方法
2018/06/08 Python
查看python安装路径及pip安装的包列表及路径
2019/04/03 Python
python实现统计文本中单词出现的频率详解
2019/05/20 Python
Python3 元组tuple入门基础
2020/02/09 Python
美国唇部护理专家:Sara Happ
2019/06/19 全球购物
网络、C以及其他硬件方面的面试题
2016/08/23 面试题
XML文档面试题
2015/08/05 面试题
班组安全员工作职责
2014/02/01 职场文书
求职信怎么写
2014/05/23 职场文书
学习十八大的心得体会
2014/09/01 职场文书
2015年检验员工作总结范文
2015/04/30 职场文书
解决pytorch 损失函数中输入输出不匹配的问题
2021/06/05 Python
Li list-style-image 图片垂直居中实现方法
2023/05/21 HTML / CSS