Loading

threading模块

  • 导入
import threading

该模块实现了多线程操作

  • 线程

 

 

 当线程需要共享数据时,可能存在数据不同步的问题,此时就引入了锁的概念

 

 

 某一个线程需要访问共享数据时,就需要请求获得锁定(可能有多个线程位于锁定池,等待获得锁定)

如果此时已经有其他线程获得锁定(最多一个进程获得锁定,处于运行状态),那么这个线程就要暂停(称之为同步阻塞)

避免出现多个线程同时访问共享数据,这样就不会出现数据不同步的情况

 

 

 

 

 

 在等待池的线程等待条件变量的通知,条件满足时则去请求锁定,此时为等待锁定

注意首先要等待通知(此时处于等待池),通知完成请求锁定(此时位于锁定池),获得锁定之后即可进入运行

 

 

同步阻塞是指处于竞争锁定的状态,线程请求锁定时将进入这个状态,一旦成功获得锁定又恢复到运行状态;
等待阻塞是指等待其他线程通知的状态,线程获得条件锁定后,调用“等待”将进入这个状态,一旦其他线程发出通知,线程将进入同步阻塞状态,再次竞争条件锁定;
而其他阻塞是指调用time.sleep()、anotherthread.join()或等待IO时的阻塞,这个状态下线程不会释放已获得的锁定

  • 创建一个线程

简单创建

t1 = threading.Thread(target=run,args=('t1',))
# target是要执行的函数名(不是函数),不要加括号
# args是函数对应的参数,以元组的形式存在
t2 = threading.Thread(target=run,args=('t2',))
# 如上方法,就为同一个run函数创建了两个线程,传入不同的参数
# 也有name参数来指定线程名
t1.start() t2.start() # 开始各个线程 t1.join() # 主线程必须等待t1这个子线程执行完成才继续执行
# 也就是阻塞当前上下文环境的线程,直到当前线程终止或超时

内置的方法

threading.currentThread()
# 返回当前的线程变量
threading.enumerate()
# 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
threading.activeCount():
# 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

通过重写类的run方法创建线程

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

class myThread (threading.Thread):
    # 通过从threading.Thread继承并创建一个新的子类
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
        添加了三个属性,分别是ID,名称,计数
    def run(self):
        print ("开始线程:" + self.name)
        print_time(self.name, self.counter, 5)
        print ("退出线程:" + self.name)
        #重写了run方法   
       

Lock有一个锁定池,当线程请求锁定时,将线程置于池中,直到获得锁定后出池

池中的线程处于状态图中的同步阻塞状态,此时就是竞争锁定

t1.acquire([timeout])
# 使线程进入同步阻塞状态,尝试获得锁定
t1.release()
# 释放锁
# 使用前线程必须已获得锁定,否则将抛出异常

 

posted @ 2020-12-09 15:42  lixin2020  阅读(382)  评论(0)    收藏  举报