Python学习笔记(三)多线程的使用
这节记录学习多线程的心得。
Python提供了thread模块,不过该模块的缺点很多,例如无法方便的等待线程结束,所以我们使用更加高级的threading模块。
threading模块的使用一共三种模式:
1.利用函数生成一个Thread实例
2.利用函数生成一个可以调用的类对象,生成一个Thread实例
3.从Thread派生一个子类,创建这个子类的实例
利用函数生成Thread实例
第一种使用方式最为简单,代码如下:
import threading
from time import sleep def threadFunc():
i = 10;
while i > 0:
print 'i = %d' % i
i -= 1 if __name__ == '__main__':
t = threading.Thread(target = threadFunc)
t.start()
t.join()
这段代码的逻辑很简单,就是在线程中执行threadFunc这个函数。
如果该函数需要参数的话,在
t = threading.Thread(target = threadFunc)
这一行添加一个参数即可,如下:
import threading
from time import sleep def threadFunc(i):
while i > 0:
print 'i = %d' % i
i -= 1 if __name__ == '__main__':
t = threading.Thread(target = threadFunc, args = [10])
t.start()
t.join()
注意args参数必须使用元组或者列表。
利用函数生成一个可以调用的类对象,生成一个Thread实例
我们先补充一些知识,C++中有函数对象,就是对某一个类重载函数调用操作符,那么该类的对象就可以当做函数来使用,python中也有同样的机制:
class Foo():
def __call__(self):
print 'foobar' if __name__ == '__main__':
f = Foo()
f()
此例中f是一个对象,但可以当做函数使用。当调用f()时,解释器调用了Foo中的__call__方法,相当于C++中的operator()操作符被重载。
还有一个关于apply的知识点:
def test(i):
print 'i = %d' % i if __name__ == '__main__':
apply(test, [1])
apply可以这样调用函数。通过这种机制,我们可以将函数存储起来,选择合适的时机注意调用。
from random import randint def foo(i):
print 'i = %d' % i
def bar(i):
print 'i*i = %d' % (i*i) class Foo():
def __call__(self, i):
print 'foobar: %d' % i if __name__ == '__main__':
funcs = [foo, bar, Foo()]
for func in funcs:
i = randint(1, 4)
apply(func, [i])
于是我们可以将函数存储在类中,为该类提供__call__函数,此时这个类的对象也是可以执行的,所以我们利用这个对象去生成Thread。
#coding: utf-8
import threading
from time import sleep class ThreadFunc(object):
def __init__(self, func, args):
self.func = func
self.args = args def __call__(self):
apply(self.func, self.args) def loop(i):
while i > 0:
print 'i = %d' % i
sleep(0.5)
i -= 1 if __name__ == '__main__':
print '在主线程内执行这个函数'
t1 = ThreadFunc(loop, [5])
t1() print '开始执行一个新的线程'
t2 = threading.Thread(target = t1)
t2.start()
t2.join()
print '线程执行完毕' print '开始执行一个新的线程'
t3 = threading.Thread(target = ThreadFunc(loop, [3]))
t3.start()
t3.join()
print '线程执行完毕'
t1是个ThreadFunc的实例,既可以直接执行,又可以使用它去生成Thread实例。
从Thread派生一个子类,创建这个子类的实例
最简单的使用方式如下:
import threading
from time import sleep class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.count = 10 def run(self):
while self.count > 0:
print 'i = %d' % self.count
sleep(1)
self.count -= 1 if __name__ == '__main__':
t = MyThread();
t.start()
t.join()
我们去继承Thread类,然后覆盖其中的run方法,这与Java的Thread使用相一致。
创建多个线程可以这样:
import threading
from time import sleep class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self) def run(self):
print 'begin .....'
sleep(5)
print 'end.....' if __name__ == '__main__':
threads = []
for i in range(10):
t = MyThread()
threads.append(t)
for t in threads:
t.start()
for t in threads:
t.join()
不过,目前我们的线程逻辑是固定的,可以借鉴第二种方式,从外部传入逻辑,存储起来。
#coding: utf-8
import threading
from time import sleep class CustomThread(threading.Thread):
def __init__(self, func, args):
threading.Thread.__init__(self)
self.func = func
self.args = args def run(self):
apply(self.func, self.args) def loop(i):
while i > 0:
print 'i = %d' % i
sleep(0.5)
i -= 1 if __name__ == '__main__':
t = CustomThread(loop, [10])
t.start()
t.join()
这里跟第二种不同的是:
1.采用了继承,基类是Thread
2.覆盖run方法,而不是提供__call__方法
3.使用时直接创建该类的实例
以上三种,我个人感觉第三种最方便,在大一些程序中,可以将该Thread单独做成一个模块。
另外,前两种的本质是一样的,都是向Thread传入一个可以执行的对象(python中函数也是对象)。
完。
Python学习笔记(三)多线程的使用的更多相关文章
- Python 学习笔记三
笔记三:函数 笔记二已取消置顶链接地址:http://www.cnblogs.com/dzzy/p/5289186.html 函数的作用: 給代码段命名,就像变量給数字命名一样 可以接收参数,像arg ...
- webdriver(python) 学习笔记三
知识点:简单的对象定位 对象的定位应该是自动化测试的核心,要想操作一个对象,首先应该识别这个对象.一个对象就是一个人一样,他会有各种的特征(属性),如比我们可以通过一个人的身份证号,姓名,或者他住在哪 ...
- python学习笔记(十三): 多线程多进程
一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...
- python学习笔记三--字典
一.字典: 1. 不是序列,是一种映射, 键 :值的映射关系. 2. 没有顺序和位置的概念,只是把值存到对应的键里面. 3. 通过健而不是通过偏移量来读取 4. 任意对象的无序集合 5. 可变长,异构 ...
- Python学习笔记三
一. 为什么要使用函数? 函数可以方便阅读代码. 函数可以减少重复代码. 函数可以减少管理操作,减少修改操作. 二. 函数分类: 内置函数:len() sum() max() min() ...
- python学习笔记(三)、字典
字典是一种映射类型的数据类型.辣么什么是映射呢?如果看过<数据结构与算法>这一本书的小伙伴应该有印象(我也只是大学学习过,嘻嘻). 映射:就是将两个集合一 一对应起来,通过集合a的值,集合 ...
- Python学习笔记三:模块
一:模块 一个模块就是一个py文件,里面定义了一些业务函数.引用模块,可以用import语句导入.导入模块后,通过 模块.函数名(参数) 来使用模块中的函数.如果存在多个同名模块,则前面模块名需要加 ...
- python学习笔记(三)高级特性
一.切片 list.tuple常常截取某一段元素,截取某一段元素的操作很常用 ,所以python提供了切片功能. L=['a','b','c','d','e','f'] #取索引0,到索引3的元素,不 ...
- python学习笔记(三):文件操作和集合
对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句柄操作文件 3.关闭文件. 文件基本操作: f = open('file.txt','r') #以只读方式打开一个 ...
- python学习笔记三:函数及变量作用域
一.定义 def functionName([arg1,arg2,...]): code 二.示例 #!/usr/bin/python #coding:utf8 #coding=utf8 #encod ...
随机推荐
- redis.clients.jedis.HostAndPort - cant resolve localhost address
阿里云ECS部署spring-boot访问redis出现redis.clients.jedis.HostAndPort - cant resolve localhost address 摘要: 阿里云 ...
- Tornado 模块概述
Tornado模块分类 1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 t ...
- laravel获取checkbox值的小技巧
以前老是用三元运算符来判断,现在有了更好的方法: 1.html代码 <input type="hidden" name="approved" value= ...
- [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集
4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1474 Solved: 521[Submit][Stat ...
- 【转】Python模块subprocess
subprocess 早期的Python版本中,我们主要是通过os.system().os.popen().read()等函数.commands模块来执行命令行指令的,从Python 2.4开始官方文 ...
- BZOJ 1185: [HNOI2007]最小矩形覆盖-旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标-备忘板子
来源:旋转卡壳法求点集最小外接矩形(面积)并输出四个顶点坐标 BZOJ又崩了,直接贴一下人家的代码. 代码: #include"stdio.h" #include"str ...
- validate+jquery+ajax表单验证
1.案例 1.1 Html form表单内容 <form class="cForm" id="cForm" method="post" ...
- dfs序七个经典问题[转]
dfs序七个经典问题 参考自:<数据结构漫谈>-许昊然 dfs序是树在dfs先序遍历时的序列,将树形结构转化成序列问题处理. dfs有一个很好的性质:一棵子树所在的位置处于一个连续区间中. ...
- []End of 2017OI
今年大概到此为止了,现在这个算是做一个简短的阶段性总结吧 今年打的第一场大概是省赛,当时整个人处于(迷茫,不知道选物理还是选信息+备战中考+持续摸鱼OI颓废)的状态,KMP都不会导致签到题都没有分,然 ...
- Android 架构 1.架构
项目分为了四个层级:模型层.接口层.核心层.界面层.模型层定义了所有的模型:接口层封装了服务器提供的API:核心层处理所有业务逻辑:界面层就处理界面的展示.几个层级之间的关系如下图所示: 层级关系:模 ...