线程进程补充概念

线程和进程的了解部分,这些概念适用于线程和进程

可以从threading和multiprocessing中导入,一样的使用。

信号量 Semaphore

信号量在不同的阶段可能对应不同的技术点,在并发编程中信号量指的是锁!!!

这种锁支持多个进程或线程批量共享数据,而不是一个一个地单独享用数据。

  • 使用模块Semaphore, 可以从threading或multiprocessing导入

    from threading import Thread, Semaphore
    # from multiprocessing import Semaphore
    sm = Semaphore(5)  # 括号内写数字 写几就表示开设几个坑位
    sm.acquire()
    sm.release()
    
  • 信号量和线程池不一样,信号量是产生一堆线程分批使用数据。

  • 线程池是固定的线程,依次处理大批量的任务。

示例

from threading import Thread, Semaphore
import time, random

sm = Semaphore(5)  # 括号内写数字 写几就表示开设几个坑位


def task(name):
    sm.acquire()
    print('%s 正在蹲坑'% name)
    time.sleep(random.randint(1, 5))
    sm.release()


if __name__ == '__main__':
    for i in range(20):
        t = Thread(target=task, args=('伞兵%s号'%i, ))
        t.start()

事件 Event

线程或进程间是可以设置依赖关系,当A结束时才能执行B。

此时可以使用事件,绑定他们之间的依赖关系。

  • 使用Event模块

    from threading import Thread, Event
    # from multiprocessing import Event
    event = Event()  	# 造了一个红绿灯
    event.set() 		# 告诉等待红灯的人可以走了,A发出通知,告诉B
    event.wait()  		# 等待别人给你发信号, B等待A的通知,
    

示例

 from threading import Thread, Event
import time


event = Event()  # 造了一个红绿灯


def light():
    print('红灯亮着的')
    time.sleep(3)
    print('绿灯亮了')
    # 告诉等待红灯的人可以走了
    event.set()


def car(name):
    print('%s 车正在灯红灯'%name)
    event.wait()  # 等待别人给你发信号
    print('%s 车加油门飙车走了'%name)


if __name__ == '__main__':
    t = Thread(target=light)
    t.start()

    for i in range(20):
        t = Thread(target=car, args=('%s'%i, ))
        t.start()

线程 Q

同一个进程下多个线程间数据共享,此时使用队列主要是为了保证数据安全(队列 = 管道 + 锁)。

  • Queue,普通队列,先进先出FIFO
  • LifoQueue, 后进先出队列, 类似堆栈,却不同(队列两个口,堆栈一个口)
  • PriorityQueue,优先队列, 支持设置消息的等级
  • 后进先出队列和优先队列都是继承的普通队列
import queue

# 普通队列, 先进先出
q = queue.Queue(3)
q.put(1)
q.get()
q.get_nowait()
q.get(timeout=3)
q.full()
q.empty()

# 后进先出队列,
q = queue.LifoQueue(3)  # last in first out
q.put(1)
q.put(2)
q.put(3)
print(q.get())  # 3

# 优先队列
q = queue.PriorityQueue(4)
q.put((10, '111'))
q.put((100, '222'))
q.put((0, '333'))
q.put((-5, '444'))
print(q.get())  # (-5, '444')
# put括号内放一个元祖  第一个放数字表示优先级, 第二个元素是消息
# 需要注意的是 数字越小优先级越高!!!,即优先get出来

定时器 Timer

定时器,指定n秒后执行某操作

from threading import Timer


def hello():
    print("hello, world")

t = Timer(1, hello)
t.start()  # after 1 seconds, "hello, world" will be printed

验证码定时器

from threading import Timer
import random,time

class Code:
    def __init__(self):
        self.make_cache()

    def make_cache(self,interval=5):
        self.cache=self.make_code()
        print(self.cache)
        self.t=Timer(interval,self.make_cache)
        self.t.start()

    def make_code(self,n=4):
        res=''
        for i in range(n):
            s1=str(random.randint(0,9))
            s2=chr(random.randint(65,90))
            res+=random.choice([s1,s2])
        return res

    def check(self):
        while True:
            inp=input('>>: ').strip()
            if inp.upper() ==  self.cache:
                print('验证成功',end='\n')
                self.t.cancel()
                break


if __name__ == '__main__':
    obj=Code()
    obj.check()

条件 Condition

使得线程等待,只有满足某条件时,才释放n个线程

import threading

def run(n):
    con.acquire()
    con.wait()
    print("run the thread: %s" %n)
    con.release()

if __name__ == '__main__':

    con = threading.Condition()
    for i in range(10):
        t = threading.Thread(target=run, args=(i,))
        t.start()

    while True:
        inp = input('>>>')
        if inp == 'q':
            break
        con.acquire()
        con.notify(int(inp))
        con.release()
def condition_func():

    ret = False
    inp = input('>>>')
    if inp == '1':
        ret = True

    return ret


def run(n):
    con.acquire()
    con.wait_for(condition_func)
    print("run the thread: %s" %n)
    con.release()

if __name__ == '__main__':

    con = threading.Condition()
    for i in range(10):
        t = threading.Thread(target=run, args=(i,))
        t.start()
posted @ 2020-04-27 16:04  the3times  阅读(138)  评论(0编辑  收藏  举报