学习python第七天

学习python第七天
多线程

#主线程与小弟线程
import _thread  #多线程,一般不用
import win32api

def show(i):
	#0代表系统,你真帅代表内容,0代表窗口类型0,1,2,3
	mystr=win32api.MessageBox(0,"你真帅",0)

for i in range(5): #小弟线程
	_thread.start_new_thread(show,(i,))
	#前面是执行函数,后面是一个元组,可以不写,前提势函数没有形参
while True:#为了主脚本不死,小弟线程才能运行
	pass


import time
def go():
	for i in range(5):
		print("------")
		time.sleep(1)
for i in range(5):#同时执行5次
	_thread.start_new_thread(go,())

for j in range(6):#主线程卡顿6秒
	timesleep(1)

print("over")
在这里插入代码片

线程冲突

import _thread

num=0
def add():
	for _ in range(1000000):
		global num
		num +=1
	print(num)

"""
for j in range(5):
	add()
"""
for i in range(5):
	_thread.start_new_therad(add,())
#这里就是线程冲突,5个线程同时抢夺num的资源,导致结果错误
"""
1110934
1358368
1342884
1392305
1464472
"""
while True:
	pass
在这里插入代码片

基于类实现多线程

import threading #常用
import win32api
class Mythread(threading.Thread): #继承therading.Thread类
	def __init__(self):
		threading.Thread.__init__(self)#父类初始化
	def run(self):
		win32api.MessageBox(0,"hello",0)

for i in rage(5):#同时创建5个线程
	t-=Mythread()
	t.start()#开启
	#等待一个线程完毕,在执行下一个线程,一方面可以阻止脚本主线成死掉,另一方面也可以防止线程冲突的一种办法
	t.join()
	#t.join() 如果放在外部的不确定因数是系统给for循环和下面的代码锁定了一片内存,当循环执行完成之后内存就开锁,但里面的东西依然存在,所以才结束一个窗体,game over就出来就和删除文件后,内存中可能还有文件一个道理
	
#while True:
	#pass
 	
在这里插入代码片

类线程的乱序

import threading
import wen32api

class Mythread(threading.Thread):
	def __init__(self,num):
		threading.Thread.__init__(self)
		self.num=num
	def run(self):
		win32api.MessageBox(,"holle"+str(sel.num),'joker',)
		print(self.getName())#获取线程名
mythd=[]
for i in range():
	t=Mythread(i)#初始化
	print(i)
	t.start()
	mythd.append(t)#将乱序线程加入列表
for j in Mythd(t):
	#这里与顺序不同,上面显示所有的线程都加入列表(一次跳出5个列表)
	j.join()
print("game over")
在这里插入代码片

基于类解决线程冲突

import threading
import time

#锁机制
num=0
mutex=threading.Lock()#创建一个锁

class Mythread(threading.Thread):
	def __init__(self):
		threading.Thread.__init(self)
	def run(self):
		global num
		if mutex.acquire(1):#如果所成功,线程继续干活,如果一直失败,下面线程一直等待
			for i in range(1000):#数字小的时候不会产生线程冲突
				num +=1
			mutex.release()#释放锁
		print(num)

mythread =[]
for i in range(5):
	t=Mythread()
	t,start()
	mythread.append(t)
for thread in mythread:
	thread.join()#把他加入上面的for,也能解决问题,但是貌似就变成了单线程了

print("game over")



#死锁(先说答案再发offer,先发offer再说答案)
boymutex=threading.Lock()
girlmutex=threading,Lock()
#创建俩个锁
class boy(threading.Thread):
	def run(self):
		if boymutexacquire(1):#锁成功继续执行,锁不成功,就一直等
			print(self.name+"boy asy i am sorry up")
			#time.sleep(3)#时间短可以并发执行,不会锁死
			if girlmutex.acquire(1):#锁不成功,因为下面已经锁死
				print(self.name+"boy say i am soory down")
				girlmutex.release()
			boymutex.release()
class girl(threading.Thread):
	def run(self):
		if girlmutexacquire(1):
			print(self.name+"girl asy i am sorry up")
			#time.sleep(3)
			if boymutex.acquire(1):
				print(self.name+"girl say i am soory down")
				boymutex.release()
			girlmutex.release()
#开启俩个线程
#boy1=bou()
#boy1.start()
#girl=girl()
#girl.start()
"""
这种例子时间过短是无法很好的产生死锁
for i in range(10):
	Mythread1().start()
	Mythread2().start()
"""
for i in range(1000):
	boy().start()
	girl().start()


#RLock
num=0
mutext=threading.RLock() #RLock避免单线程死锁

class Mythreading(threadingThread):
	def run(self):
		global num
		if mutext.acquire(1):
			num +=1
			print(self.name,num)
			if mutext.acquire(1):
				num +=1000
				mutext.release()
			mutext.release()
for i in range(5):#开启五个线程
	t=mythreading()
	t.start()		
在这里插入代码片

创建多线程

#第一中用函数创建多线程,但是需要处理让脚本主线程不死
import threading
import win32api

class Mythread(threading.Thread):
	def run(self):
	win32api.MessageBox(0,"hello",0)

Mythd=[]
for i in range(5):
	t=Mythread()#初始化
	print(i)
	t.start
	Mythd.append(t)#将乱序线程加入列表
for j in Mythd:
	#这里与顺序不同,上面显示所有的线程都加入Mthd列表,j是线程
	j.join()
print("game over")


#第二种基于类继承创建线程

class Mythread(threading.Thread):
	defrun(self):
		win32api.MessageBox(0,'hello',0)

for i in range(5):
	t=Mythread()
	t.start()


#基于函数够着细线多线程
def show(i):	
	win32api.MessageBox(0,"这是一个测试",0)
threading.Thread(target=show,args=(i,)).start()
threading.Thread(target=show,args=(i,)).start()
在这里插入代码片

限制与匹配线程数量

import threading
import time
sem=threading.Semaphore(2)#限制最大线程数为2个
def gothread():
	with sem:#锁定数量
		for i in range(10):
			print(threading.current_thread().name,i)#打印线程名字
			time.sleep(1)

for i in range(5):
	threading.Thread(target=gothread).start()#乱序执行多线程,就可以考虑为有些cpu牛逼些能够执行快一点


#为了合理利用资源
#凑出线程数量,也就是说一定要至少凑成两个才能执行
#换言而之,也就是说只有创建线程数是2,或者2的倍数才能全部执行
bar=threading.Barrier(2)
def sever():
	print(threading.current_thread().name,"start")
	bar.wait()
	print(threading.current_thread().name,"end")
for i in range(3):
	threading.thread(target=sever).start()
	
在这里插入代码片

线程通信

def goevent():
	e=threading.Event()#事件
	def go():
		for i in rage(10):
			e.wait()#等待事件,线程卡顿,等待set消息,只调用一次
			e.clear()#重置线程等待
			print("go",i)
	threading.Thread(target=go).start()#创建一个线程
	return e
t=goevet()
for i in range(5):
	time.sellp(i)
	t.set()#发送消息

condition线程通信讯与事件

import threading
import time
def go1():
	with cond:
		for i in range(10):
			time.sleep(1)
			print(threading.current_thread().name,i)
			if i==5:
				cond.wait()#等待,只有在其他相同线程条件变量唤醒时才能继续执行
				#print("hahaha")
				cond.notify()#唤醒
				print("hahahahahaha")
"""
wait()此方法释放底层锁,然后阻塞,直到它通过notify()或notify_all()调用唤醒相同的条件在另一个线程中变量,或直到发生可选的超时,一旦唤醒或超时,它重新获得锁定并返回
"""
def go2():
	with cond:#试用条件变量
		for i in range(10):
			time.sellp(1)
			print(threading.current_thread().name,i)
		cond.notify()#通知唤醒其他线程
		cond.wait()#锁定
'''
notify()
在这种情况下唤醒一个或多个线程,如果有的话。
如果调用线程没有获得这个方法的锁称为,引发了一个RuntimeError。这个方法至多唤醒n个等待条件的线程变量; 如果没有线程正在等待,那么这是一个无操作。
'''

cond=threading.Condition()#线程条件变量
threading.Thread(target=go1).start()
threading.Thread(target=go2).start()

'''
代码逻辑
cond只有一个,线程1线锁定cond,当线程1跑到i==5的时候此时进入condition等待,将资源释放出来,
这时候线程2进入,一口气全部跑完i,跑到最后以cond.notifly通知将资源再放出来,此时线程1重新锁定
'''
在这里插入代码片

生产者与消费者模式

import threading
import time
import queue

q = queue.Queue(maxsize=10)


def producer(name):  # 生产者
    count = 1
    while True:
        q.put("骨头%s" % count)
        print("生产了骨头", count)
        count += 1
        time.sleep(0.5)


def consumer(name):  # 消费者
    while True:
        print("[%s]取到[%s]并且吃了它..." % (name, q.get()))
        time.sleep(1)


p = threading.Thread(target=producer, args=("Tim",))#创建线程
c1 = threading.Thread(target=consumer, args=("King",))
c2 = threading.Thread(target=consumer, args=("Wang2",))
c3 = threading.Thread(target=consumer, args=("Wang3",))
c4 = threading.Thread(target=consumer, args=("Wang4",))
c5 = threading.Thread(target=consumer, args=("Wang5",))

p.start()#启动
c1.start()
c2.start()
c3.start()
c4.start()
c5.start()
在这里插入代码片

线程池

import threadpool  # 需要安装
import time

def show(name):
    print('hello', name)
namelist = ["A", "B", "C", "D"]
start = time.time()
pool = threadpool.ThreadPool(7)  # 线程池最大数,貌似还要远大于列表长度
requests = threadpool.makeRequests(show, namelist)  # 设置参数,函数,参数列表
print(requests)
print()
for req in requests:
    pool.putRequest(req)  # 压入线程池开始执行

end = time.time()
print(end - start)
在这里插入代码片

定时线程

import time
import threading
import os

def show():
	while True:
		time.sleep(3)
		print("say hello")
mythreading=threading.Timer(3,show).start()#延迟3秒启动show函数,只启动一次,不阻塞主线程
num=0
while True:
	print("第",num,'秒')
	time.sleep(1)
	num +=1
#ythreading.cacel()#因为cancel取消了线程的执行,所以fun()hanshu不会被执行
在这里插入代码片

with的作用

import threading
num=0
mutex=threading.Lock()#创建一个锁
class Mythread(threading.Thread):
	def run(self):
		global num
		with mutex:#with作用自动打开和释放
			for i in range(100000):#数字小的时候不会产生线程冲突
			num +=1
		print(num)

mythread=[]
for i in range(5):
	t.Mythread()
	t.start()
	ythread.append(t)
for thread in mythread:
	thread.join()#
print("game over")
在这里插入代码片

后台线程

import threading
import time
class Mythread(threading.Thread):
	def run (self):
		print('hahahaha')

mythread=[]
for i in range(5):
	t=Mythread()
	t.setDaemon(True)#后台线程,主线程不等后台线程
	t.start()
	mythread.append(t)#加入线程集合
#threading.Thread默认是前台进程,主线程必须等前台
print("game voer")
在这里插入代码片

你可能感兴趣的:(学习python第七天)