#创建多线程
import time
import threading
def listening():
for i in range(5):
print("我在听歌")
time.sleep(1)
def run():
for i in range(5):
print("我在跑步")
time.sleep(1)
def main():
#创建线程对象
t1 = threading.Thread(target=listening)
t2 = threading.Thread(target=run)
#启动线程
t1.start()
#启动线程
t2.start()
if __name__ == "__main__":
main()
'''
小结:
target的值是函数名
这个函数通过run()方法得到调用,函数的参数就是创建线程对象得到的参数
在线程启动时,通过run()方法会执行这个函数
'''
'''
线程对象调用join()方法,子线程的内容执行完,才会回到主线程执行路线
这里子线程的内容,包括子线程间的切换,多个子线程执行完成后,再回到
主线程执行。所以线程对象调用join()方法,将程序分为两个执行路线:所有的子线程,主线程。并且在执行子线程时,只有当子线程执行完成,才会回到主线程执行。
下面的例子用到了join()方法,在子线程执行完成后再执行主线程中的打印时间,不会在子线程没有执行完成就回到主线程打印时间,这个时间并不是总的时间。
'''
import threading
import time
a = time.time()
list1 = ['烧水','煮饭','煲汤','蒸蛋']
def dinner():
for i in list1:
print(i)
time.sleep(0.5)
def learning():
for i in range(4):
print('看书')
time.sleep(0.5)
#创建线程对象,以调用的方式运行相应的函数
t1 = threading.Thread(target=dinner)
t2 = threading.Thread(target=learning)
t1.start()
t2.start()
t1.join()
t2.join()
b = time.time()
print(format(b-a))
#单线程任务完成时间和多线程进行比较
import threading
import time
a = time.time()
list1 = ['烧水','煮饭','煲汤','蒸蛋']
def dinner():
for i in list1:
print(i)
time.sleep(0.5)
def learning():
for i in range(4):
print('看书')
time.sleep(0.5)
dinner()
learning()
b = time.time()
print(format(b-a))
'''
小结:想要在子线程执行完成之前,中途不回到主线程执行,线程对象可以使用join()方法。
'''
#线程子类1
import time,threading
class mythread(threading.Thread):
def run(self):
for i in range(5):
print('You know, I like iced tea!')
self.drink()
def drink(self):
for i in range(4):
print('Also Coca-Cola!')
m = mythread()
m.start()
#线程子类2
import time,threading
list1 = ['cat','dog','bird','lion']
list2 = ['老虎','狮子','大象']
class mythread(threading.Thread):
def run(self):
for i in list1:
print(i)
time.sleep(0.5)
self.abc()
def abc(self):
for i in list2:
print(i)
time.sleep(0.5)
def dop():
for i in range(10):
print(i)
time.sleep(0.5)
if __name__ == '__main__':
m = mythread()
n = threading.Thread(target=dop)
m.start()
n.start()
'''
super()函数
从定义的角度:在子类中,重新定义函数,是在父类的基础上进行函数功能的拓展
是子类函数功能的进化,除了有父类函数的功能,还增加了其它功能。
从函数调用的角度:在子类函数中调用父类对应的函数
类属性同函数一样
'''
class A():
def __init__(self,a,b):
self.a = a
self.b = b
def han_shu(self):
print('类里面的第一个函数')
print(self.a,self.b)
class B(A):
def __init__(self,c,a,b):
self.c = c
super().__init__(a,b)
self.han_shu()
def han_shu(self):
super().han_shu()
print(self.c,'父类的属性ab的值为',self.a,self.b)
b = B(1,2,3)
#功能函数传入参数
import threading,time
def one(a):
for i in range(5):
print(a,'会再得到一个冠军吗?')
time.sleep(1)
def two(a,b):
for i in range(5):
print(a,b,'都认为james一定会再得到一个冠军')
time.sleep(1)
m = threading.Thread(target=one,args=('james',))
n = threading.Thread(target=two,args=('杨毅','王猛'))
m.start()
n.start()
#使用父类的run()函数,而且增加初始化参数
import threading
def han_shu():
print('输出功能的函数')
class mythread(threading.Thread):
def __init__(self, a, target=None):
self.a = a
super(mythread, self).__init__()
self._target = target
def run(self):
for i in range(5):
print('You know, I like iced tea!')
self.drink()
self.zhi()
super().run()
def drink(self):
for i in range(4):
print('Also Coca-Cola!')
def zhi(self):
print('target和n的值为', self._target, self.a)
m = mythread(1, target=han_shu)
m.start()
# 使用父类的run()函数,而且增加初始化参数,增加run()方法调用的函数的形参
import threading
def han_shu(a,b):
print('函数除了有输出功能,还有比较数字大小的功能')
if a > b:
print('第一个的值要大')
elif a == b:
print('两个数字相等')
else:
print('第二个的值要大')
class mythread(threading.Thread):
def __init__(self, a, target=None,args=()):
self.a = a
super(mythread, self).__init__()
#_target是函数的私有属性,在子类中应重新赋值,否则target的值仍为None
self._target = target
self._args = args
def run(self):
for i in range(5):
print('You know, I like iced tea!')
self.drink()
self.zhi()
#调用父类的run()方法
super().run()
def drink(self):
for i in range(4):
print('Also Coca-Cola!')
def zhi(self):
print('target和n的值为', self._target, self.a)
m = mythread(1, target=han_shu,args=(2,3))
m.start()
#多线程共享变量
import threading,time
num = 1000000
def text1(times):
global num
for i in range(times):
num += 1
print(num)
def text2(times):
global num
for i in range(times):
num += 1
print(num)
def main():
t1 = threading.Thread(target=text1,args=(100,))
t2 = threading.Thread(target=text2,args=(100,))
t1.start()
time.sleep(1)
t2.start()
time.sleep(1)
print(num)
if __name__ == '__main__':
main()
'''
小结:多线程可以共享全局变量,当全局变量有变化时,所有子线程中的
全局变量都是实时变化,全局变量的状态信息是共享的。
'''
#互斥锁用法
'''
互斥锁:当多线程共享全局变量时,为了不让数据混乱,保证数据的安全,
给线程上锁,然后在该线程中使用全局变量,在解锁之前,其它线程无法使用。
更改完成后,再解锁,让其它线程可以使用这个全局变量。
'''
import threading
#模块threading的类Lock创建锁对象
mutx = threading.Lock()
num = 100000000
a = 100000000
def text1(times):
#声明全局变量
global num
#上锁
mutx.acquire()
for i in range(times):
num += 1
#解锁
mutx.release()
print(num)
def text2(times):
#声明全局变量
global num
#上锁
mutx.acquire()
for i in range(times):
num += 1
#解锁
mutx.release()
print(num)
def main():
t1 = threading.Thread(target=text1,args=(a,))
t2 = threading.Thread(target=text2,args=(a,))
t1.start()
t2.start()
print(num)
if __name__ == '__main__':
main()
'''
Mark:假如每个线程有一个关于全局变量的任务,比如每个线程让
全局变量加1000000,为了让每个线程很好的完成它的任务,在对
全局变量进行操作时,使用互斥锁。因为完成变量的增加,会有
几个步骤,有时一个线程中还没来得及完成最终的赋值操作,
其它的线程又开始操作全局变量了,所以为了避免资源竞争,在
一个线程对全局变量进行操作时,加上互斥锁,使用完毕后,再
解锁,让其它线程操作全局变量。
'''
'''
多线程可以共享全局变量,操作全局变量时,想要不被其它线程影响,可以给操作上锁,操作完毕后,解锁。
'''
python 多线程编程(补充)
最新推荐文章于 2023-03-02 21:29:00 发布