赞
踩
是python程序中实现多任务的一种方式。线程是程序执行的最小单位。同属一个进程的多个线程共享进程所拥有的的全部资源。
步骤:
a 导入线程模块 import threading
b 创建子线程并指定执行的任务
sing_thread=threading.Thread(target=sing)
c启动线程执行任务
sing_thread.start()
线程执行带有参数的任务时,可用args(以元组方式传参)或 kwargs(以字典方式传参)
- import threading # 导入线程模块
- import time # 导入时间模块
-
-
- def sing(x): # 构造函数
- for i in range(x):
- print("唱歌")
- time.sleep(2) # 休眠2秒
-
-
- def dance(y): # 构造函数
- for i in range(y):
- print("跳舞")
- time.sleep(2) # 休眠2秒
-
-
- t1=threading.Thread(target=sing, args=(1,)) # 创建子进程t1并指定执行的任务sing,使用args传参
- t2 = threading.Thread(target=dance, kwargs={"y": 2}) # 创建子进程t2并指定执行的任务dance,使用kwargs传参
- # 启动线程执行任务
- t1.start()
- t2.start()
-
使用类来创建多线程
- import threading # 导入线程模块
- import time # 导入时间模块
-
-
- class MyThread(threading.Thread): # 定义类,继承自threading.Thread这个基类
- def __init__(self, n): # 初始化 ,并传递参数n
- super(MyThread, self).__init__()
- self.n = n
-
- def run(self): # 启动线程的函数,此种方式创建多线程,函数名只能为run,不能自定义
- print('以类的方式创建多线程', self.n)
- time.sleep(3)
-
-
- r1 = MyThread(11) # 实例化对象
- r2 = MyThread(22)
-
- r1.start() # 启动线程
- r2.start()
多线程的特性 : 主线程会等待所有子线程结束之后才会结束程序
为什么需要线程锁?
多个线程对同一个数据进行修改时, 可能会出现不可预料的情况.
例如实现银行转账功能,money += 1 这句其实有三个步骤 money; money+1; money=money+1;假如这三步骤还没完成money-=1的线程就开始执行了,后果可想而知,money的值肯定时乱的
如何实现线程锁?
1. 实例化一个锁对象;
lock = threading.Lock()
2. 操作变量之前进行加锁
lock.acquire()
3. 操作变量之后进行解锁
lock.release()
B站线程锁例子:
- import threading # 导入线程模块
-
-
- def test(): # 构造函数
- global x # 全局变量x
- lock.acquire() # 申请一把线程锁
- x += 1
- lock.release() # 操作x之后将线程锁释放
-
-
- if __name__ == '__main__':
- x = 0
- res = [] # 定义一个空列表
- lock = threading.Lock() # 对线程里面的锁进行实例化
-
- for i in range(100): # 起100个多线程
- t = threading.Thread(target=test)
- t.start()
- res.append(t) # 将线程加入列表
-
- for t in res: # 遍历列表
- t.join()
- print(x) # 输出线程个数 100
-
例子2:银行存钱和取钱
- import threading
-
-
- # 银行存钱和取钱
- def add(lock):
- global money # 生命money为全局变量
- for i in range(1000000):
- # 2. 操作变量之前进行加锁
- lock.acquire()
- money += 1 # money; money+1; money=money+1;
- # 3. 操作变量之后进行解锁
- lock.release()
-
-
- def reduce(lock):
- global money
- for i in range(1000000):
- # 2. 操作变量之前进行加锁
- lock.acquire()
- money -= 1
- # 3. 操作变量之后进行解锁
- lock.release()
-
-
- if __name__ == '__main__':
- money = 0
- # 1. 实例化一个锁对象;
- lock = threading.Lock()
-
- t1 = threading.Thread(target=add, args=(lock,))
- t2 = threading.Thread(target=reduce, args=(lock,))
- t1.start()
- t2.start()
- t1.join()
- t2.join()
-
- print("当前金额:", money)
视频网址 69-Python多线程-递归锁_哔哩哔哩_bilibili
- import threading
-
-
- def run1():
- global x
- lock.acquire()
- x += 1
- lock.release()
- return x
-
-
- def run2():
- global y
- lock.acquire()
- y += 1
- lock.release()
- return y
-
-
- def run3():
- lock.acquire()
- res1 = run1()
- res2 = run2()
- print(res1, res2)
- lock.release()
-
-
- if __name__ == '__main__':
- x = 0
- y = 0
- lock = threading.RLock()
- for i in range(50):
- s = threading.Thread(target=run3())
- s.start()
-
- while threading.activeCount() != 1:
- print(f"正在运行{threading.activeCount()}个线程")
-
- print("程序运行结束")
作业:在一个线程中,每秒循环输出当前的年月日分秒,与此同时,在另一线程中,实现张三的姓名每2秒打印输出4次结束。注意:都需要使用类和继承来实现功能
不使用类创建:
- import threading # 导入线程模块
- import time # 导入时间模块
-
-
- def date(): # 构造方法
- while True:
- time.sleep(1) # 休眠1秒
- print(time.strftime('%Y-%m-%d %X')) # 输出当前时间(年月日分秒)
-
-
- def run(): # 构造方法
- while True:
- time.sleep(3) # 休眠3秒
- print("张三")
-
-
- t1 = threading.Thread(target=date) # 创建子线程t1并指定执行的任务date
- t2 = threading.Thread(target=run) # 创建子线程t2并指定执行的任务run
-
- t1.start() # 启动线程
- t2.start()
使用类创建:
- import time # 导入线程模块
- import threading # 导入时间模块
-
-
- class First(threading.Thread): # 定义First类,继承自threading.Thread这个基类
- def run(self): # 构造函数
- while True:
- localtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) # 输出当前时间
- print(localtime)
- time.sleep(1) # 休眠一秒
-
-
- class Second(threading.Thread): # 定义second类,继承自threading.Thread这个基类
- def __init__(self, name): # 初始化 ,并传递参数name
- super(Second, self).__init__()
- self.name = name
-
- def run(self): # 启动线程的函数,此种方式创建多线程,函数名只能为run,不能自定义
- for i in range(4): # 张三姓名输出4次后结束
- print(self.name)
- time.sleep(0.5) # 每打印一次后暂停0.5秒
-
-
- if __name__ == '__main__':
- t1 = First() # 实例化对象
- t2 = Second("张三")
- t1.start() # 启动线程执行任务
- t2.start()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。