"""author = Zard"""
import threading
from time import sleep
from datetime import datetime
主线程和子线程
默认情况下,进程有一个线程,这个线程叫主线程 -- 主线程是系统自动创建的
默认所有的代码都是在主线程中执行
程序猿通过代码创建的线程都叫子线程
创建子线程
python中内置的threading模块中提供了和线程操作相关的类和方法
threading模块中有个Thread类,这个类或者这个的子类的对象就是线程对象;
需要子线程的时候就创建Thread类的对象
def download(name):
print(' %s 开始下载:%s ' % (datetime.now(),name))
print(threading.current_thread()) # 查看当前执行的线程
sleep(5)
print(' %s 下载结束:%s ' % (datetime.now(),name))
if __name__ == '__main__':
# download('龙猫')
# download('你的名字')
创建线程对象
1)语法
Thread(target=函数,args=实参列表) -- 返回子线程对象
2)说明
target - 必须要赋一个函数,这个函数会在子线程中调用
args - 赋一个元组,元组中的元素就是调用target函数的时候需要传的参数
创建2个子线程
t1 = threading.Thread(target=download,args=('龙猫',))
t2 = threading.Thread(target=download,args=('你的名字',))
2.让子线程开始执行
线程对象,start() -- 在子线程中调用target对应download,并且将args中的值作为实参
t1.start()
t2.start()
程序的结束(进程的结束)
一个进程是否结束,看是否这个进程中的每个线程都结束
线程结束:任务执行完成,遇到exit(),发生异常(只针对发生的线程)
线程中遇到exit(),线程直接结束
程序出现异常只会影响一个线程
from threading import *
from time import sleep
from datetime import datetime
推荐使用,类似于面向对象的方式
通过创建Thread类的子类对象来创建 子线程
1)声明一个类继承Thread
class DownloadThread(Thread):
def __init__(self,name):
super().__init__()
self.name = name
2)实现run方法,这个方法中的代码就是会在子线程中执行的代码
def run(self) -> None:
print(' %s 开始下载:%s ' % (datetime.now(),self.name))
print(current_thread()) # 查看当前执行的线程
sleep(5)
print(' %s 下载结束:%s ' % (datetime.now(), self.name))
if __name__ == '__main__':
# 3)创建子类的线程对象
t1 = DownloadThread('你是魔鬼吗?')
# 4)通过start去执行子线程中的任务
t1.start()
t2 = DownloadThread('程序猿猝死案例集锦')
t2.start()
练习:用套接字实现,一个服务器同时处理多个客户端的功能(一个server可以同时和多个人进行聊天)
from socket import *
from threading import *
# 创建多线程
class Chat(Thread):
def __init__(self,connection,address):
super().__init__()
self.connection = connection
self.address = address
def run(self) -> None:
while True:
re_message = self.connection.recv(1024).decode(encoding='utf-8')
print(self.address,re_message)
message = '你是**吗?'
self.connection.send(message.encode())
创建服务器对象
server = socket()
# 绑定ip地址
server.bind(('10.7.160.56',8888))
# 开始监听
server.listen(100)
# 服务器不断运行
print('开始监听...')
while True:
connection,address = server.accept()
print('有新用户!')
t1 = Chat(connection,address)
t1.start()
from threading import *
from datetime import *
from time import *
from random import randint
class Download(Thread):
def __init__(self,name):
super().__init__()
self.name = name
def run(self) -> None:
print('%s - 开始下载 %s'%(datetime.now(),self.name))
t = randint(2,6)
sleep(t)
print('%s - 下载完成 %s'%(datetime.now(),self.name))
if __name__ == '__main__':
print('=========================无忧==========================')
t1 = Download('素人初摄.avi')
t2 = Download('丧心病款.avi')
t3 = Download('夜蒲团子.mp4')
t2.start()
t1.start()
t3.start()
join的使用
线程对象.join()
其他的代码
这儿的其他的代码会等到指定的线程对象结束后才会执行
t1.join()
t2.join()
t3.join()
from threading import Thread,Lock,RLock
from time import sleep
怎么加锁
1)保证一个数据对应一把锁:创建锁对象
2)使用数据前加锁:锁对象.acquire()
3)保证数据使用完成后释放锁:锁对象.release()
数据
account = 1000
1.创建锁对象
lock = Lock()
def save_money(num):
# 2.加锁
lock.acquire()
print('开始存钱')
global account
balance = account
sleep(4)
account = balance + num
# 3.释放锁
lock.release()
print('余额:%d'% account)
def draw_money(num):
print('开始取钱')
# 2.加锁
lock.acquire()
global account
balance = account
if balance < 0:
print('余额不足')
return
sleep(4)
account = balance - num
print('余额:%d'% account)
# 3.释放锁
lock.release()
t1 = Thread(target=save_money,args=(1000,))
t2 = Thread(target=draw_money,args=(500,))
t1.start()
t2.start()