文章目录
1.创建线程的基本方法
① 继承Thread
import threading
# 第一种 继承Thread
class MyThread(threading.Thread):
def __init__(self, thread_name):
super(MyThread, self).__init__(name=thread_name)
def run(self):
print("%s 在执行中..." % self.name)
for i in range(10):
MyThread("testThread" + str(i)).start()
for i in range(10): 添加10个子线程
② 不使用类的方法
import threading
def show(num):
print('当前线程: %d 在执行...' % num)
for i in range(10):
t = threading.Thread(target=show, args=(i,))
t.start()
2.守护线程
① 模拟子线程处理时间
import threading
import time
def dowaiting():
print('子线程开始等待...')
time.sleep(3)
print("子线程执行结束")
print("主线程开始")
t = threading.Thread(target=dowaiting)
t.start()
print("主线程的其他操作")
t.join() # 合并主线程子线程,让主线程等待子线程执行完毕
print("主线程结束")
使用 join( )会让程序成为单线程,慎用join( )
② 增加线程名
import threading
import time
def dowaiting():
print(threading.current_thread().getName() + '子线程开始等待...')
time.sleep(3)
print(threading.current_thread().getName() + "子线程执行结束")
print("主线程开始")
for i in range(3):
t = threading.Thread(target=dowaiting)
t.start()
print("主线程结束")
③ 由主线程控制子线程的开始和关闭 (子线程为守护线程)
import threading
import time
def dowaiting():
print(threading.current_thread().getName() + '子线程开始等待...')
time.sleep(3)
print(threading.current_thread().getName() + "子线程执行结束")
print("主线程开始")
for i in range(3):
t = threading.Thread(target=dowaiting)
t.setDaemon(True) # 主线程控制子线程
t.start()
print("主线程结束")
.setDameon( ) 默认为False
3.线程安全
① 线程不安全,脏数据
import threading
import time
number = 0
def add():
global number
for _ in range(1000000):
number += 1
print("子线程 %s 执行结束后: number = %d" % (threading.current_thread().getName(), number))
for i in range(2):
t = threading.Thread(target=add)
t.start()
time.sleep(3)
print("主线程结束,number = " + str(number)) # 结果为两个数按顺序轮流各自加自己的数,互不相关,Thread-2没有加上Thread-1,没有达到算出2000000的结果
# Thread-1: 1000
# Thread-2: 1000
# Thread-1: 2345
# Thread-2: 2456
# ...
global + 含数的变量 作用: 在局部函数对全局变量重新赋值
② 线程锁_with语句
import threading
import time
number = 0
lock = threading.Lock()
def add(lk): # lock为局部变量,需要传入方法中
global number
# 加锁
with lk:
for _ in range(1000000):
number += 1
print("子线程 %s 执行结束后: number = %d" % (threading.current_thread().getName(), number))
# 解锁
for i in range(2):
t = threading.Thread(target=add, args=(lock,))
t.start()
time.sleep(3)
print("主线程结束,number = " + str(number))
args= 作用: 传入参数
③ 线程锁_互斥锁
import threading
import time
number = 0
lock = threading.Lock()
def add(lk):
global number
# 加锁 独占线程
lk.acquire()
for _ in range(1000000):
number += 1
print("子线程 %s 执行结束后: number = %d" % (threading.current_thread().getName(), number))
# 解锁
lk.release()
for i in range(2):
t = threading.Thread(target=add, args=(lock,))
t.start()
time.sleep(3)
print("主线程结束,number = " + str(number))
互斥锁:同一时刻只能被一个线程访问
for _ in range( ):中" _ " 表示无意义
args=(lock,)元组(括号)内的元素(参数)分别为lk.acquire( )和lk.release( )内的参数