python自学-class22(down)-python线程基础学习

python线程基础学习

1. 线程通信‘
2. 线程通信强化
3. condition线程通信与事件
4. 线程调度
5. 生产者消费者模式
6. 线程池
7. 定时线程
8. with用法
9. 前台线程
10. TLS

++++++++++++++++++++++++++++++++++++++++++++++
1.线程通信:
用set来激发事件以达到通知效果

import threading
import time

def goevent():
    e=threading.Event()  #事件
    def go():
        e.wait()   #等待,后续代码不执行,等待set再执行
        e.clear()  #清理
        print("go")
    threading.Thread(target=go).start()  #开启一个线程
    return e
t=goevent()
time.sleep(5)        #5s后才激发事件打印go
t.set()  #激发事件

2.线程通信强化(传参):

import threading
import time

def goevent():
    e=threading.Event()  #事件
    def go():
        for i in range(10):
            e.wait()    #等待
            e.clear()   #重置
            print(i,"go")
    threading.Thread(target=go).start()  #开启一个线程
    return e
t=goevent()
for i in range(10):
    time.sleep(i)        # i s后才激发事件打印go
    t.set()   #通知

3.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()
def go2():
    with cond:  #使用条件变量
        for i in range(10):
            time.sleep(1)
            print(threading.current_thread().name,i)
        cond.notify()   #通知
cond=threading.Condition()  #线程条件变量
threading.Thread(target=go1).start()
threading.Thread(target=go2).start()

4.线程调度用condition条件控制实现:

import threading
import time

def go1():
    with cond:
        for i in range(1,10,2):
            time.sleep(1)
            print(threading.current_thread().name,i)
            cond.notify()   #通知
            cond.wait()    #等待

def go2():
    with cond:
        for i in range(0,10,2):
            time.sleep(1)
            print(threading.current_thread().name,i)
            cond.wait()
            cond.notify()

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

5.生产者-消费者模式
生产者-消费者模式,即生产者负责生产(往队列增加数据,但是有一定限度,满了即不再生产),消费者负责消费(从队列取出数据,队列为空则等待生产),以下是简单模拟生产者消费者模式:

import threading
import queue
import time
import random
#生产
class creatorTread(threading.Thread):
    def __init__(self,index,myqueue):
        threading.Thread.__init__(self)
        self.index=index    #索引
        self.myqueue=myqueue #队列
    def run(self):
        while True:
            time.sleep(3)   #3秒生产一个
            num=random.randint(1,100000)   #随机数
            self.myqueue.put("input 生产者"+str(self.index)+"奶茶"+str(num))
            print("input 生产者"+str(self.index)+"奶茶"+str(num))
        self.myqueue.task_done()   #代表完成任务,在这里不执行

#消费
class buyerTread(threading.Thread):
    def __init__(self,index,myqueue):
        threading.Thread.__init__(self)
        self.index=index    #索引
        self.myqueue=myqueue #队列
    def run(self):
        while True:
            time.sleep(1)
            item=self.myqueue.get()  #抓取数据
            if item is None:
                break
            print("客户",self.index,"物品",item)
        self.myqueue.task_done()  # 代表完成任务,在这里不执行

myqueue=queue.Queue(10)   #0表示无限,10代表最大容量为10
for i in range(3):
    creatorTread(i,myqueue).start()   #3个生产者
for i in range(8):
    buyerTread(i,myqueue).start()    #8个消费者

6.线程池(threadpool):
创建线程池来控制线程数量,线程压入线程池后开始执行

import time
import threadpool   #线程池

def show(str):
    print("hello",str)
    time.sleep(2)
namelist=["xiaoming","177"]
start_time=time.time()
pool=threadpool.ThreadPool(10)  #最大容量
requests=threadpool.makeRequests(show,namelist)   #设置参数,并发十个线程干活,函数,参数列表

for req in requests:   #遍历每一个请求,并开始执行
    pool.putRequest(req)  #压入线程池开始执行

end_time=time.time()
print(end_time-start_time)

'''
def show(str):
    print("hello",str)
    time.sleep(2)
namelist=["xiaoming","177","szu"]
start_time=time.time()
for name in namelist:
    show(name)
end_time=time.time()
print(end_time-start_time)
'''

7.定时线程
延时线程的执行

import time
import os
import threading
'''
i=0
while True:
    time.sleep(1)
    print("第",i,"秒")
    i+=1
'''
def go():
    while True:
        time.sleep(3)
        os.system("notepad")
timethread=threading.Timer(5,go)   #延时5s后执行go,执行一次
timethread.start()
i=0
while True:
    time.sleep(1)
    print(i)
    i+=1

8.with:
使用锁(LOCK)的过程中,可以使用with,来自动释放锁,用法如下:

import threading
import time

num=0   #全局变量多个线程可以读写,可用于线程传递数据,但需要用到event
mutex=threading.Lock()   #创建一个锁
class Mythread(threading.Thread):
    def run(self):
        global num
        with mutex:
        #if mutex.acquire(1):   #锁住成功,没有锁住成功则一直等待,1代表参数,独占
            for i in range(100000):   #锁定期间其他人不能干活
                num+=1
            #mutex.release()  #释放锁
        print(num)
mythread=[]
for i in range(5):
    t=Mythread()
    t.start()
    mythread.append(t)
for t in mythread:
    t.join()

print("over!")

'''
with mutex:   #with自动打开,自动释放
#if mutex.acquire(1):   #锁住成功,没有锁住成功则一直等待,1代表参数,独占
    for i in range(100000):   #锁定期间其他人不能干活
        num+=1
'''

9.前台与后台线程
主线程必须等待前台线程执行,而不必要等待后台线程,threading.Thread默认是前台进程,主线程必须等前台

import threading
import time
import win32api
class Mythread(threading.Thread):      #继承threading.Thread
    def run(self):    #run重写
        win32api.MessageBox(0,"你的账户很危险","来自支付宝的问候",2)

mythread=[]  #list
for i in range(5):
    t=Mythread()   #初始化
    #t.setDaemon(True)    #后台线程,主线程不等待后台线程
    t.start()
    mythread.append(t)   #加入线程集合
#threading.Thread默认是前台进程,主线程必须等前台
print("over")

10.TLS
线程之间独立存储空间,是动态绑定的

import threading
import time
data = threading.local()  #每个线程独立存储空间
t1=lambda x:x+1
t2=lambda x:x+"1"
def printdata(func,x):  #func代表函数,x代表参数
    data.x=x  #data是一个类,动态绑定,线程互相独立,=1  =“1”,data.x每个线程中是独立的
    print(id(data.x))
    for i in range(5):
        data.x=func(data.x)
        print(threading.current_thread().name,data.x)
threading.Thread(target=printdata,args=(t1,1)).start()
threading.Thread(target=printdata,args=(t2,"1")).start()

总结

线程才刚刚开始,还很不熟练,具体的应用也不掌握,线程很重要,还需要加强练习。

猜你喜欢

转载自blog.csdn.net/weixin_46837674/article/details/113827842