黑马多任务---线程

一:线程:两个函数同时执行

import time
import threading

def sing():
	for i in range(5):
		print("我正在唱歌......")
		time.sleep(1)
		
def dance():
	for i in range(5):
		print("我正在跳舞......")
		time.sleep(1)
	
def main():
	t1 = threading.Thread(target = sing)
	t2 = threading.Thread(target = dance)
	t1.start()
	t2.start()

if __name__ == "__main__":
	main()

在这里插入图片描述
单核CPU:同一时间只能做同一件事情。
过程解析:程序一旦启动,立刻会生成一个主线程,当程序运行到t1.start(),的时候程序此时出现有一个子线程,这个子线程会从sing方法开始执行,知道sing方法结束。当主线程运行到t2.start()的时候,程序此时出现有一个子线程,这个子线程会从dance方法开始执行,知道dance方法结束。

二:查看当前线程的运行数:

import threading

def test1():
	for i in range(5):
		print("------test1---- %d" % i)
def test2():
	for i in range(5):
		print("------test2---- %d" % i)

def main():
	t1 = threading.Thread(target = test1)
	t2 = threading.Thread(target = test2)
	t1.start()
	t2.start()

	print(threading.enumerate())
	
if __name__ == "__main__":
	main()

对于这样一个代码,当t1,t2,所在的线程启动时,此时主线程和两个子线程分别强资源,导致打印出的线程可能是主线程也可能是子线程中的任何一个。

如果让test1先执行,然后test2,最后主线程,怎么增加休眠??

import threading
import time

def test1():
	for i in range(5):
		print("------test1---- %d" % i)
def test2():
	for i in range(5):
		print("------test2---- %d" % i)

def main():
	t1 = threading.Thread(target = test1)
	t2 = threading.Thread(target = test2)
	t1.start()
	
	# 主线程休眠一秒钟,让t1线程执行完。
	time.sleep(1)
	
	t2.start()
	# 主线程休眠一秒钟,让t2线程执行完。
	time.sleep(1)
	
	# 此时打印的一定是主线程
	print(threading.enumerate())
	
if __name__ == "__main__":
	main()

此时的输出应该是:先打印5次test1,再打印5次test2,最后打印出主线程(最后只有主线程)。同样道理,如果要想让t2先执行,只需要 t2.start()先开始,再休眠。t1.start()再开始 ,再休眠即可。但是如果让主线程先执行呢?需要在t1,t2函数内进行延时,此时主线程先死呢还是会等待t1,t2执行完呢?测试:

import threading

def test1():
	for i in range(5):
		print("------test1---- %d" % i)
		time.sleep(1)
		
def test2():
	for i in range(5):
		print("------test2---- %d" % i)
		time.sleep(1)

def main():
	t1 = threading.Thread(target = test1)
	t2 = threading.Thread(target = test2)
	t1.start()
	t2.start()

	print(threading.enumerate())
	print("主线程执行完了")
	
if __name__ == "__main__":
	main()

在这里插入图片描述
这也就是说:在子线程没结束前,主线程不会先执行完,要等子线程执行完,主线程才结束。
子线程什么时间结束?
答:如果创建Threading指定的函数运行结束,那么标志着子线程结束。

三:Thread(target = 函数名),target可不可以指定一个类呢?
特点:这个类必须继承threading.Thread这个类。并且这个类必须具有run方法,因为这个类的对象调用start()方法的时候会默认调用类中的run方法。

import threading
import time
class MyThread(threading.Thread):
	def run(self):
		for i in range(3):
			time.sleep(1)
			msg = self.name + ":" + str(i)
			print(msg)
			# 在run方法里可以调用其他方法,构成整个功能模块。
			self.login()
			self.register()
			
	def login(slef):
		print("这是登录模块的代码....")
		
	def register(self):
		print("这是注册模块的代码....")	
	
if __name__ == "__main__":
	# 这里定义类的对象,此时子线程没有创建
	t = MyThread()
	# 当调用start方法的时候子线程创建了,会主动调用run方法
	t.start()
	

问题:在run方法中调用login和redgster是一共三个线程还是只有一个线程???
答:只有一个线程,定义几个MyThread()对象,执行几个start()方法就有几个线程,run方法内是在一个线程内。

四:多线程之间共享全局变量

import threading
import time

g_num = 100

def test1():
	global g_num
	g_num += 1
	print("in test" + g_num)
	
def test2():
	print("out test" + g_num)

def main():
	t1 = thread.Thread(target = test1)
	t2 = thread.Thread(target = test2)
	
	t1.start()
	time.sleep(1)
	
	t2.start()
	time.sleep(1)
    
    print("main test" + g_num)
if __name__ == "__main__":
	main()

解析:如果多线程之间共享全局变量,则三个都是101,如果不是 则是 101 100 100
即:对于g_num 这个变量,主线程和t1 t2线程,是共享的。

验证:既然是共享变量的,那么也可以将一个数据传给每个线程分别执行呀??

import threading
import time

def test1(temp):
	g_num.append(33)
	print("-------test1------ %s", str(temp))

def test1(temp):
	print("-------test2------ %s", str(temp))	

g_num = [11,22]

def main():
	
	# 这里必须传入元组Thread的第二个参数必须是元组
	t1 = threading.Thread(target=test1, (g_num,))
	t2 = threading.Thread(target=test2, (g_num,))
	
	t1.start()
	time.sleep(1)
	
	t2.start()
	time.sleep(1)

	print("------main---%s", str(g_num))

if __name__ == "__main__":
	main()

利用g_num 将数据传递给两个子线程分别进行修改。

五:多线程存在的问题:
两个线程:一个线程写文件,另一个也写文件,就会产生资源竞争。上个案例一个写,一个读所以不会出现资源竞争。
在这里插入图片描述
解释:对于同样一个全局变量,当第一个线程拿到获取获取到g_num(0),并且加一后还没有重新赋值给g_num的时候,操作系统由于时间到了,便让这个线程阻塞,让另外一个线程继续执行,而这个线程重新取到的数据还是(0),此时让他全部执行完,g_num变成了(1),当第二个线程全部执行完后,第一个线程由阻塞状态变成执行状态,此时第一个线程又把1赋值给了g_num。这样结果就导致,两个线程分别加一次,但是最后结果却只增加1。这就是资源竞争。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奈何碎银没有几两

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值