这节记录学习多线程的心得。

 

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学习笔记(三)多线程的使用的更多相关文章

  1. Python 学习笔记三

    笔记三:函数 笔记二已取消置顶链接地址:http://www.cnblogs.com/dzzy/p/5289186.html 函数的作用: 給代码段命名,就像变量給数字命名一样 可以接收参数,像arg ...

  2. webdriver(python) 学习笔记三

    知识点:简单的对象定位 对象的定位应该是自动化测试的核心,要想操作一个对象,首先应该识别这个对象.一个对象就是一个人一样,他会有各种的特征(属性),如比我们可以通过一个人的身份证号,姓名,或者他住在哪 ...

  3. python学习笔记(十三): 多线程多进程

    一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...

  4. python学习笔记三--字典

    一.字典: 1. 不是序列,是一种映射, 键 :值的映射关系. 2. 没有顺序和位置的概念,只是把值存到对应的键里面. 3. 通过健而不是通过偏移量来读取 4. 任意对象的无序集合 5. 可变长,异构 ...

  5. Python学习笔记三

    一. 为什么要使用函数? 函数可以方便阅读代码. 函数可以减少重复代码. 函数可以减少管理操作,减少修改操作. 二. 函数分类: 内置函数:len()   sum()   max()   min() ...

  6. python学习笔记(三)、字典

    字典是一种映射类型的数据类型.辣么什么是映射呢?如果看过<数据结构与算法>这一本书的小伙伴应该有印象(我也只是大学学习过,嘻嘻). 映射:就是将两个集合一 一对应起来,通过集合a的值,集合 ...

  7. Python学习笔记三:模块

    一:模块 一个模块就是一个py文件,里面定义了一些业务函数.引用模块,可以用import语句导入.导入模块后,通过 模块.函数名(参数)  来使用模块中的函数.如果存在多个同名模块,则前面模块名需要加 ...

  8. python学习笔记(三)高级特性

    一.切片 list.tuple常常截取某一段元素,截取某一段元素的操作很常用 ,所以python提供了切片功能. L=['a','b','c','d','e','f'] #取索引0,到索引3的元素,不 ...

  9. python学习笔记(三):文件操作和集合

    对文件的操作分三步: 1.打开文件获取文件的句柄,句柄就理解为这个文件 2.通过文件句柄操作文件 3.关闭文件. 文件基本操作: f = open('file.txt','r') #以只读方式打开一个 ...

  10. python学习笔记三:函数及变量作用域

    一.定义 def functionName([arg1,arg2,...]): code 二.示例 #!/usr/bin/python #coding:utf8 #coding=utf8 #encod ...

随机推荐

  1. docker从零开始(四)集群初体验,docker-machine swarm

    介绍 在第三节中,选择了第二节中编写的应用程序,并通过将其转换为服务来定义它应如何在生产中运行,并生成五个应用实例 在本节中,将此应用程序部署到群集上,在多台计算机上运行它.多容器,多机应用程序通过连 ...

  2. linux下命令行文件路径隐藏

    https://askubuntu.com/questions/16728/hide-current-working-directory-in-terminal 在~.,bashrc里添加 expor ...

  3. spring applicationContext.xml 中bean配置

    如果采用set get方法配置bean,bean需要有set get 方法需要有无参构造函数,spring 在生成对象时候会调用get和set方法还有无参构造函数 如果采用constructor方法则 ...

  4. WN7下安装office2013编辑文档反应这么慢?

    把office在高级选项里面“禁用硬件加速”给打勾就OK了. [office 2013密钥] 9MBNG-4VQ2Q-WQ2VF-X9MV2-MPXKV F2V7V-8WN76-77BPV-MKY36 ...

  5. 在Debian 9上安装和配置Observium网络监控

    https://blog.csdn.net/csgd2000/article/details/80780697

  6. set注入

    顾名思义set注入必须要有set方法. 基本类型的注入.引用类型注入.List注入.Set注入.Map注入.Properties注入 public class person { private car ...

  7. ionic 之环境的搭建

    在ionic的学习中,首先要做的就是环境的搭建,接下来我对从一开始环境的搭建做了记录,以及过程中遇到的问题. 1.安装环境 1.1 安装Node.js Node.js建议安装最新版本,下载地址:htt ...

  8. 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y))

    layout: post title: 训练指南 UVA - 11383(KM算法的应用 lx+ly >=w(x,y)) author: "luowentaoaa" cata ...

  9. 区间DP【p2858】[USACO06FEB]奶牛零食Treats for the Cows

    Description 约翰经常给产奶量高的奶牛发特殊津贴,于是很快奶牛们拥有了大笔不知该怎么花的钱.为此,约翰购置了N(1≤N≤2000)份美味的零食来卖给奶牛们.每天约翰售出一份零食.当然约翰希望 ...

  10. 使用DFS求任意两点的所有路径

    先上代码: public static void findAllPaths(Integer nodeId,Integer targetNodeId, Map<Integer,ArrayList& ...