在介绍多线程之前,先来介绍下Python中的类。算是给像我这样,从java或c++转入python的小白一些“前车之鉴”。
python作为面向对象的语言,自然也会有类、属性、继承...这些概念。而基于以往的java经验,我打算自定义一个类来实现多线程。
好吧,开始写class MyThread:,然后定义属性,啥?要给成员变量赋值?这不是构造函数做的事吗??算了,先不管属性,写构造函数吧。class MyThread():...报错!这是什么情况??哦,要用 def __init__...嗯,总算定义好了一个类,来个实例试试, MyThread mt = ...又报错!哦,不能这样写啊?早说嘛!!!(注:该段是错误操作,纯属娱乐)
好了,废话写了一堆,下面直接上研究成果,真可谓“不懂真是难,懂了真简单”
# coding=UTF-8
'''python中类的简单介绍
'''
class human: # 定义human类
'''构造函数:
self必须有,等价于'this'
name、age为human的属性,即成员变量,前面加双下划线'__'表示为私有,不能被继承,赋值时:self.__xx=xx
'''
def __init__(self, name, age):
self.name = name # 为成员变量赋值
self.age = age
def speak(self):
print '我会说话'
class man(human): # 定义man类,继承human类。注:括号中为父类列表
def __init__(self, name, age, sex): # 重写父类构造方法,可增加自己的属性,如sex
human.__init__(self, name, age) # 调用父类的构造函数
self.sex = sex
def speak(self): # 重写父类方法
print '我是男人,我也会说话'
def fun(self): # 定义无参方法,self为必须有的,不算参数
print '我是男人,我力气大'
def sing(self, song): # 定义有参方法
print '我是男人,我会唱' + song
class woman(human): # 定义woman类,继承human类
def __init__(self, name, age, sex):
human.__init__(self, name, age)
self.sex = sex
def speak(self):
print '我是女人,我也会说话'
def setName(self, name): # 定义设置name属性的函数,即set方法
self.name = name
def getName(self): # 定义获取name属性的函数,即get方法
return self.name
def test(obj): # 定义实现多态的函数,参数obj相当于 java中的 'human obj',即一个父类引用型变量
print # 换行
print '名字:', obj.name
print '年纪:', obj.age
obj.speak()
# 测试
if __name__ == '__main__':
h = human('人', '500万年') # 创建human类对象
m = man('小明', 18, '男')
w = woman('小芳', 20, '女')
# human类测试
test(h) # 传入不同的类对象
# man类测试
test(m)
print '性别:', m.sex # 打印男人的sex属性
m.fun() # 测试无参函数
m.sing('情歌') # 测试有参函数
# woman类测试
test(w)
print '性别:', w.sex
print '我原来的名字是:', w.getName()
w.setName('小红') # 更改name属性
print '现在我的名字是:', w.getName()
运行结果:
现在总算对类有个简单的了解了,那下面来聊聊多线程吧。
多线程,顾名思义,就是多个线程同时工作,如果将一个线程比作一个任务的话,那就是多个任务同时进行。比如我,现在就是边听歌,边写博客。而这,就是一个简单的多线程例子。
定义暂时搞清楚了,但问题又来了,用多线程究竟有什么好处呢?俗话说,光说不练假把式!下面我们就来做个小实验,看看多线程的“好处”何在。
# coding=utf-8
import threading
import time
class MyThread(threading.Thread): # 定义线程类继承 threading.Thread
def __init__(self, group, target, name, args):
threading.Thread.__init__(self, group, target, name, args)
'''重写父类的构造函数。
group:线程组,未实现,但实例化时必须有这个参数,设为None
target:指向线程要绑定的函数
name:线程名
args:绑定函数的所需参数,为元组类型
'''
def listen(sname): #定义要绑定运行的函数
for i in range(7):
print threading.current_thread().getName(), '--我在听' + sname
time.sleep(2)
def read(bname):
for j in range(7):
print threading.current_thread().getName(), '--我在读' + bname
time.sleep(3)
ts = [] # 创建线程列表
t1 = MyThread(None, listen, '线1', ('一辈子孤单',))
t2 = MyThread(None, read, '线2', ('平凡的世界',))
# 实例化时要根据参数顺序传入,args参数要写成元组形式,一个元素时,加逗号避免歧义
ts.append(t1)
ts.append(t2)
if __name__ == '__main__':
for t in ts: # 遍历线程列表
t.setDaemon(True) # 设为守护线程,主线程结束后所有子线程立即结束,写在start方法前!
t.start() # 启动线程
t.join() # 在所有子线程结束前一直阻塞主线程的结束,一定写在线程循环外!!写在循环内会成单线程...
print '主线程:', threading.current_thread().getName(), '结束'
线程的join、setDaemon等方法,想详细了解的点这里点击打开链接
运行结果:
# coding=utf-8
import threading
import time
'''单线程测试'''
def listen(sname):
for i in range(7):
print '我在听' + sname
time.sleep(2) # 每次听2秒
def read(bname):
for j in range(7):
print '我在读' + bname
time.sleep(3) # 每次读3秒
if __name__ == '__main__':
print'开始时间:', time.ctime()
listen('一辈子孤单')
read('平凡的世界')
print '结束时间:', time.ctime()
'''多线程测试'''
# class MyThread(threading.Thread): # 定义线程类继承 threading.Thread
#
# def __init__(self, group, target, name, args):
# threading.Thread.__init__(self, group, target, name, args)
# '''重写父类的构造函数。
# group:线程组,未实现,但实例化时必须有这个参数,设为None
# target:指向线程要绑定的函数
# name:线程名
# args:绑定函数的所需参数,为元组类型
# '''
#
# def listen(sname):
# for i in range(7):
# print threading.current_thread().getName(), '--我在听' + sname
# time.sleep(2)
#
# def read(bname):
# for j in range(7):
# print threading.current_thread().getName(), '--我在读' + bname
# time.sleep(3)
#
# ts = [] # 创建线程列表
# t1 = MyThread(None, listen, '线1', ('一辈子孤单',))
# t2 = MyThread(None, read, '线2', ('平凡的世界',))
# # 实例化时要根据参数顺序传入,args参数要写成元组形式,一个元素时,加逗号避免歧义
# ts.append(t1)
# ts.append(t2)
# if __name__ == '__main__':
# # print '开始时间:', time.ctime()
# for t in ts: # 遍历线程列表
# t.setDaemon(True) # 设为守护线程,主线程结束后所有子线程立即结束,写在start方法前!
# t.start() # 启动线程
# t.join() # 在所有子线程结束前一直阻塞主线程的结束,一定写在线程循环外!!写在循环内会成单线程...
# print '主线程:', threading.current_thread().getName(), '结束了'
# # print '结束时间:', time.ctime()
测试时注释一方,运行另一方即可。下面是测试结果。
可见,多线程最大的用处就是节约时间,因为它的总用时,只是最耗时的任务所用时间!当然,并不是所有的情况都适合用多线程,总的来说,多线程最适合的应用场景是“I/0密集型任务”。啥?不知道这是什么?那还不快去问问度娘,补充下知识。