多线程的特性
多线程类似于同时执行多个不同程序,多线程运行有如下优点:
使用线程可以把占据长时间的程序中的任务放到后台去处理。
用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
程序的运行速度可能加快。
在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。
而初始化多线程有两种方法
第一种是函数方法:
import threading
import time
def test(x):
print(x)
time.sleep(2)
t1 = threading.Thread(target=test,args=(1,))
t2 = threading.Thread(target=test,args=(2,))
t1.start()
t2.start()
而第二种则是类方法:
import threading
import time
class MyThread(threading.Thread):
def __init__(self, n):
super(MyThread, self).__init__()
self.n = n
def run(self):
print('以类的方式创建多线程', self.n)
time.sleep(2)
r1=MyThread(11)
r2=MyThread(22)
r1.start()
r2.start()
这两种方法都可以进行多线程。
而对于在执行的过程中如果查看所执行的线程,则需要以下语句:
print(threading.active_count())
线程锁
多个线程对同一个数据进行修改时, 可能会出现不可预料的情况,这个时候我们则需要线程锁来进行锁定执行。
如下面:
import threading
def run():
global x #设置全体变量
lock.acquire() #操作变量之前进行加锁
x += 1
lock.release() #操作变量之后进行解锁
if __name__ == '__main__':
x = 0 #定义变量x
res = [] #定义列表
lock = threading.Lock() #实例化一个锁对象
#创建多线程
for i in range(100):
t = threading.Thread(target=run)
t.start()
res.append(t) #写入列表
for t in res:
t.join()
print(x)
递归锁
但线程锁在使用的过程中会涉及到嵌套,此时线程锁则有可能在嵌套的过程中出现记录错误的情况,此时我们引进递归锁。
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()
lock.release() # 操作变量之后进行解锁
print(res1,res2)
if __name__ == '__main__':
x = 0
y = 0
lock = threading.RLock() #实例化一个锁对象
for i in range(50):
t = threading.Thread(target=run3)
t.start()
while threading.active_count() != 1:
print(f'正在运行{threading.active_count()}个线程')
print('线程运行结束!')
而对于题目中,在一个线程中,每秒循环输出当前的年月日时分秒;于此同时,
在另一个线程中,实现张三的姓名每2秒打印输出4次结束。
import threading #导入threading模块
import time #导入time模块
import datetime #导入datetime模块
class MyThread(threading.Thread): # 创建多线程的第一个类
def __init__(self, n): #初始化方法
super(MyThread, self).__init__() #继承父类方法
self.n = n #定义初始化变量
def run(self): #重写父类方法
while (True):
print(datetime.datetime.now()) #输出当前时间
time.sleep(self.n) #打印停止1秒
class MyThrea(threading.Thread):# 创建多线程的第二个类
def __init__(self, name): #初始化方法
super(MyThrea, self).__init__() #继承父类方法
self.name = name #定义初始化变量
def run(self): #重写父类方法
for i in range(4): #for循环执行4次输出张三
print(self.name)
time.sleep(2) #打印5停止2秒
r1=MyThread(1) #实例化对象
r2=MyThrea("张三") #实例化对象
r1.start() #开始执行线程
r2.start() #开始执行线程