day19-多线程
2018-11-29 本文已影响0人
2333_11f6
19.1 耗时操作
一个进程默认有一个线程,这个线程叫主线程。默认情况下,所有的代码都是在主线程中执行的。
import time,datetime
def download(file_name):
print('开始下载:%s' % file_name, datetime.datetime.now())
time.sleep(5) # 程序执行到这会停5秒,再执行后面的代码
print('%s下载结束' % file_name, datetime.datetime.now())
# 在主线程中下载俩个电影
download('小黄人')
download('地心游记')
19.2 多线程
python中提供threading模块来支持多线程技术
默认创建的线程叫主线程,其它的线程叫子线程,如果希望代码在子线程中执行,必须手动创建线程对象。
import threading
import time,datetime
def download(file_name):
print('开始下载:%s' % file_name, datetime.datetime.now())
time.sleep(5) # 程序执行到这会停5秒,再执行后面的代码
print('%s下载结束' % file_name, datetime.datetime.now())
print(threading.current_thread()) # 当前线程
# # 在主线程中下载俩个电影
# download('小黄人') # <_MainThread(MainThread, started 14148)>
#
# download('地心游记') # <_MainThread(MainThread, started 14148)>
1.创建线程对象
a.Thread - 线程类
b.Thread(target=函数名,args=参数列表) - 直接创建线程对象,返回线程对象
函数名 - 需要在当前创建的子线程中执行的函数变量
参数列表 - 元组,元组的元素是函数的参数元组,注意参数只要1个时别忘了逗号。
t1 = threading.Thread(target=download, args=('小黄人', ))
t2 = threading.Thread(target=download, args=('地心游记', ))
2.在子线程中执行任务
在这就是调用t1对应的线程中调用download函数,并传1个参数’小黄人‘
t1.start() # <Thread(Thread-1, started 16228)>
t2.start() # <Thread(Thread-2, started 15660)>
19.3 线程类子类
from threading import Thread,current_thread
创建子线程除了直接创建Thread对象,还可以创建这个类的子类对象
注意:一个进程有多个线程,进程会在所有的线程结束后才结束
# 1.声明一个类,继承Thread
class DownloadThread(Thread):
# 想要给run方法传值,通过添加对象属性来传
def __init__(self, filename):
super().__init__()
self.filename = filename
# 重写run方法
def run(self):
# 这里的代码会在子线程中执行
print('run')
print(current_thread())
# 3.创建线程对象
t1 = DownloadThread('789')
# 4.通过线程对象调用start在子线程中执行run方法
t1.start() # <DownloadThread(Thread-1, started 17764)>
t1.run() # 主线程执行<_MainThread(MainThread, started 18984)>
19.4 join函数
线程对象.join() - 等待线程对象执行完成
import time,datetime,random
from threading import Thread
class DownThread(Thread):
def __init__(self, file_name):
super().__init__()
self.file_name = file_name
def run(self):
print('开始下载:%s' % self.file_name)
t = random.randint(5, 12)
time.sleep(t)
print('结束下载:%s' % self.file_name)
print('耗时%d秒' % t)
if __name__ == '__main__':
t1 = DownThread('小黄人')
t2 = DownThread('黄人')
time1 = time.time()
t1.start()
t2.start()
t1.join()
t2.join()
# t1和t2都执行完成后才执行 time2
time2 = time.time()
print('总用时%d秒' % (time2-time1))
19.5 数据共享
import time
from threading import Thread
import threading
当多个线程同时对一个数据进行操作时,可能会出现数据混乱
多个线程对一个数据进行操作,一个线程将数据读出来,还没来得及存进去,另一个线程又去调用该数据,这时可能产生数据安全隐患。
解决方式是给数据加锁
Thread - 创建子线程
Lock - 锁;创建锁对象
class Account(object):
def __init__(self, balance, name):
self.balance = balance # 余额
self.name = name
self.lock = threading.Lock() # 创建锁对象
def save(self, num):
print(self.name, '开始存钱')
# 加锁
self.lock.acquire()
old_balance = self.balance
time.sleep(3)
self.balance = old_balance + num
# 解锁
self.lock.release()
def draw(self, num):
print(self.name, '开始取钱')
# 加锁
self.lock.acquire()
old_balance = self.balance
time.sleep(3)
self.balance = old_balance - num
# 解锁
self.lock.release()
account1 = Account(1000, '小黄人')
# 支付宝存钱
t1 = Thread(target=account1.save, args=(1000, ))
# 银行卡取钱
t2 = Thread(target=account1.draw, args=(500, ))
t1.start()
t2.start()
t1.join()
t2.join()
print(account1.balance)