一、多线程
import time
from datetime import datetime
import threading #专门提供和线程相关的操作
每一个进程都有一个线程,这个线程叫主线程;其他的线程都叫子线程
def download(film_name):
print('开始下载: %s' % film_name, datetime.now())
time.sleep(5)
print('%s下载完成' % film_name, datetime.now())
# 在一个线程里面,下两个电影
# download('齐天大圣')
# download('007')
# 2、线程模块
# 1)current_thread函数 -- 获取当前线程
print(threading.current_thread())
# 2)Thread类
'''
Thread类的对象就是线程,所有需要就创建这个类的对象。
Thread(target,*args,**kwargs)
target -- 函数,需要在当前创建的子线程中调用的函数
args/kwargs -- 调用target中的函数需要的实参列表
'''
# a.创建线程对象
t1 = threading.Thread(target=download, args=('齐天大圣',) )
# t1 = threading.Thread(target=download,kwargs={'film_name':'齐天大圣')
t2 = threading.Thread(target=download, args=('007',) )
# b.开始执行子线程中的任务:线程对象.start()
# 通过start方法在子线程中去调用target对应的函数
t1.start()
t2.start()
二、自己重写Thread
# 1、创建自己的线程类:
'''
1)声明一个类,继承Thread
2)实现run方法,这个方法中的任务就是需要再子线程中执行的任务
'''
class DowLoadThread(Thread):
def __init__(self,file_name):
super().__init__()
self.file_name = file_name
def run(self):
# print(current_thread())
# print('在子线程中执行的代码')
print('开始下载:%s' % self.file_name, datetime.now())
time.sleep(4)
print('结束下载: %s' % self.file_name, datetime.now())
def p(self):
print('kkkkkkkkkkkkkkkkkk')
# 3)用子类直接创建线程对象
t1 = DowLoadThread('红警')
t2 = DowLoadThread('坦克')
# 4)通过start取执行子线程中的任务
t1.start()
t2.start()
# t1.run() # 不能直接调用run方法,因为这样调用不会在子线程中执行任务。这样调用就直接是在主线程中执行的。
# 注意:一个进程中如果有多个线程,程序会在所有线程都结束才结束。
# 发送异常崩溃其实崩溃的是线程。
三、如果希望某个任务是在某个线程结束后才执行,那就将这个任务的代码放在对应线程对象调用join方法的后面
from datetime import datetime
from threading import *
import time
from random import randint
class DownLoadThread(Thread):
def __init__(self, name, time):
super().__init__()
self.name = name
self.time = time
def run(self):
print('开始下载:%s' % self.name, datetime.now())
# time.sleep(randint(5, 10))
time.sleep(self.time)
print('下载结束:%s' % self.name, datetime.now())
t1 = DownLoadThread('龙珠GT', 7)
t2 = DownLoadThread('魂斗罗', 4)
t1.start()
t2.start()
# 1、join
'''
如果希望某个任务是在某个线程结束后才执行,
那就将这个任务的代码放在对应线程对象调用join方法的后面
'''
t1.join()
print('over')
四、多线程中防止数据错乱
1、问题:
当多个线程同时对一个数据进行读写操作,可能会出现一个线程刚把数据读出来,
还没把数据写进去,另一个线程进行读操作,而出现的数据安全问题。
2、解决 -- 加锁
1)保证每个数据对应一个锁对象
2)操作数据前加锁,数据操作完成后释放锁
# 锁的使用:
'''
1、问题:
当多个线程同时对一个数据进行读写操作,可能会出现一个线程刚把数据读出来,
还没把数据写进去,另一个线程进行读操作,而出现的数据安全问题。
2、解决 -- 加锁
1)保证每个数据对应一个锁对象
2)操作数据前加锁,数据操作完成后释放锁
'''
class Account:
def __init__(self, name, tel, balance):
self.name = name
self.tel = tel
self.balance = balance
# 关联一个锁对象
self.lock = Lock()
def save_money(self, money):
# 加锁
self.lock.acquire()
print('开始存钱')
value = self.balance
time.sleep(4)
self.balance = value + money
print('存钱成功:%.2f' % self.balance)
# 释放锁
self.lock.release()
def draw_money(self, money):
self.lock.acquire()
print('开始取钱')
value = self.balance
time.sleep(5)
if value < money:
print('取钱失败,余额不足')
return
self.balance = value - money
print('取钱成功:%.2f' % self.balance)
self.lock.release()
acount = Account('H', '1880', 10000)
# 一个线程存钱
t1 = Thread(target=acount.save_money, args=(1000,))
t2 = Thread(target=acount.draw_money, args=(500,))
# t1.start()
# t2.start()
share_data = 1000
lock = Lock()
def add_data(value):
lock.acquire()
global share_data
old_data = share_data
time.sleep(3)
share_data = value+old_data
lock.release()
t3 = Thread(target=add_data,args=(200,))
t4 = Thread(target=add_data, args=(300,))
t3.start()
t4.start()
t3.join()
t4.join()
print(share_data)
网友评论