Python 之并发编程之线程下

七.线程局部变量

多线程之间使用threading.local 对象用来存储数据,而其他线程不可见

实现多线程之间的数据隔离

本质上就是不同的线程使用这个对象时,为其创建一个只属于当前线程的字典

拿空间换时间的方法

例:

from threading import local, Thread

 

loc = local()

print(loc)  # 是个对象

 

 

def func(name, age):

    global loc

    loc.name = name

    loc.age = age

    print(loc.name, loc.age)

 

 

# 创建第一个线程

t1 = Thread(target=func, args=("one", 98))

t1.start()

 

# 创建第二个线程

t2 = Thread(target=func, args=("two", 19))

t2.start()

 

八.线程事件

例:

from threading import Event,Thread

import time,random

 

'''

# wait()  动态添加阻塞

#set()    将内部属性改为True

#clear()  将内部属性改成False

#is_set() 判断当前属性(默认为False)

 

语法:

e = Event()

print(e.is_set())

# wait(timeout = 3) 最多阻塞等待3秒

e.wait(3)

print(e.is_set())

'''

 

def check(e):

    print("开始检测数据连接的合法性")

    time.sleep(random.randrange(1,7))

    e.set()

 

def connect(e):

    sign = False

    # 最多尝试连接3次数据库,连接不上就报错,报错时等待错误,TimeoutError

    for i in range(3):

        e.wait(1)

        if e.is_set():

            sign = True

            print("数据库连接成功")

            break

        else:

            print("尝试连接数据库%s次失败" % (i+1))

 

    if sign ==False:

        # 主动抛出异常

        raise TimeoutError

 

e = Event()

# 创建线程1

Thread(target=check,args=(e,)).start()

 

#创建线程2

Thread(target=connect,args=(e,)).start()

九.条件

例:

 

from threading import Condition, Thread

import time

 

'''

wait 和 notify 是一对

    wait 负责添加阻塞

    notify 负责释放阻塞

    语法: 无论是wait 还是notify ,在使用时,前后必须上锁

    

#(1) 语法: wait 前后上锁

acquire()

wait()

..code..

release()

 

#(2) 语法:notify 前后上锁

acquire()

notify(自定义释放多少阻塞,释放多少线程数量,默认放下1个)

release()

 

'''

def func(con,index):

    print("%s在等待" % (index))

    con.acquire()

    # 添加阻塞

    con.wait()

    print("%s do something" % (index))

    con.release()

 

con = Condition()

for i in range(10):

    t = Thread(target=func,args=(con,i))

    t.start()

 

time.sleep(1)

# 写法一

con.acquire()

 

#一次性释放所有阻塞,所有线程

#con.notifyAll()

con.notify(10)

con.release()

 

#写法二

# count = 10

# while count>0:

# num = int(input(">>>\n"))

# con.acquire()

# con.notify(num)

# con.release()

# count-=num

 

十.定时器

# Timer 几秒之后执行某个任务

from threading import Timer

def func():

    print("正在执行某任务。。。")

 

# Timer(时间,执行的任务)

t = Timer(3,func)

t.start()

print("主线程...")

 

# 在实际生产中,利用linux的计划任务来取代 , crontab 来取代

 

十一.队列

import queue

# from queue import Queue

"""

put     往队列里放值,超过队列长度,直接阻塞

get     获取值,如果获取不到,阻塞

put_nowait()    如果放入的值超过了,队列长度,直接报错

get_nowait()    如果获取的值已经没有了,直接报错

 

"""

# (1)queue 先进先出

'''

q = queue.Queue()

q.put(1)

q.put(2)

print(q.get())

#print(q.get())

#print(q.get()) #值不够取,产生阻塞

# 线程中支持get_nowait

print(q.get_nowait())

'''

 

# 可以限制队列的长度

'''

q = queue.Queue(2)

q.put(3)

q.put(4)

#q.put(5)  #发生阻塞

q.put_nowait(6)   # 报错: queue.Full

 

'''

 

# (2) lifoQueue 后进先出(数据结构中,栈队列的存取顺序)

'''

from queue import LifoQueue

lq = LifoQueue()

lq.put(1)

lq.put(2)

print(lq.get())

 

'''

 

# (3) PriorityQueue 按照优先顺序排序

from queue import  PriorityQueue

'''

默认按照数字大小排序,然后再按照ascii编码排序

'''

pq = PriorityQueue()

pq.put( (12,"zhangsan")  )

pq.put( (6, "lisi" )     )

pq.put( (6,"lijiujiu")   )

pq.put( (18,"wangwu" )   )

print(pq.get())

print(pq.get())

print(pq.get())

print(pq.get())

 

# 单独一个元素,必须放同一种类型,

# (1)如果是数字 [默认从小到大排序]

pq = PriorityQueue()

pq.put(13)

pq.put(18)

pq.put(3)

# pq.put("abc")

 

print(pq.get())

print(pq.get())

print(pq.get())

# print(pq.get())

 

# (2) 如果是字符串 [默认按照ascii编码从小到大排序]

pq = PriorityQueue()

pq.put("aabb")

pq.put("ddbb")

pq.put("ccbb")

pq.put("王五")

pq.put("李四")

# pq.put(990) #error

print(pq.get())

print(pq.get())

print(pq.get())

上一篇:优先队列及堆排序


下一篇:【快排】数组第k大元素 LeetCode - 215. Kth Largest Element in an Array