• python3 线程_threading模块


    '''
    并发:同一个时间段内运行多个程序的能力

    进程就是一个程序在一个数据集上的一次动态执行过程。进程一般由程序、数据集、进程控制块三部分组成

    程序:食谱
    数据集:鸡蛋、牛奶、糖等
    进程控制块:记下食谱做到哪一步了

    线程:最小的执行单元,程序中具体代码 比如:食谱中的具体操作方法
    进程:最小的资源管理单元,线程,数据等等 比如:整个食谱

    切换的操作者:操作系统
    进程/线程切换原则:
    1、时间片
    2、遇到IO操作切换 代码执行input()函数时,本身不占cpu了,输入完成后再切回来。conn,client_addr = sock.accept()执行后不占cpu了,
    开启了另一个有关监听的线程,当接收到数据是再切给accept

    串行、并行、并发
    并发的关键是你有处理多个任务的能力,不一定要同时。
    并行的关键是你有同时处理多个任务的能力。
    所以说,并行是并发的子集


    IO密集型任务:程序存在大量IO操作
    计算密集型任务:程序存在大量计算操作

    对于PYTHON的多线程处理:
    IO密集型任务有优势
    计算密集型任务不推荐使用多线程

    '''


    多线程
    import threading
    import time
    
    def foo(n):
        print('>>>>>%s' %n)
        time.sleep(3)
    
    def bar(n):
        time.sleep(5)
        print('>>>>>%s' %n)
    
    s = time.time()
    
    t1 = threading.Thread(target=foo,args=(2,))
    t1.start()    # .start()方法激活线程,可以去抢cpu执行
    
    t2 = threading.Thread(target=bar,args=(5,))
    t2.setDaemon(True)  # 主线程结束不等待子线程
    t2.start()
    
    t1.join()  # 加入主线程阻塞
    # t2.join()
    
    print('ending!')
    print('cost time:',time.time()-s)

    线程的类继承式创建

    import threading
    import time
    
    class MyThread(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            # super().__init__()
    
        def run(self):
            print('OK')
            time.sleep(2)
            print('end t1')
    
    t1 = MyThread()
    t1.start()
    print('ending')

    线程三把锁

    互斥锁

    import threading
    import time
    
    def sub():
        global num
    
        lock.acquire()
    
        temp = num
        time.sleep(0.1)
        num = temp-1
    
        lock.release()
    
        time.sleep(2)
    
    num = 100
    
    lock = threading.Lock()
    
    l = []
    for i in range(100):
        t = threading.Thread(target=sub,args=())
        t.start()
        l.append(t)
    
    for t in l:
        t.join()
    
    print(num)

    递归锁

    import threading
    import time
    
    class MyThread(threading.Thread):
    
        def __init__(self):
            super().__init__()
    
        def run(self):
            self.foo()
            self.bar()
    
        def foo(self):
            RLock.acquire()
            print('I am %s GET LOCKA-----%s' %(self.name,time.ctime()))
    
            RLock.acquire()
            print('I am %s GET LOCKB-----%s' %(self.name,time.ctime()))
            RLock.release()
            # time.sleep(1)
    
            RLock.release()
            # time.sleep(1)
    
        def bar(self):
            RLock.acquire()
            print('I am %s GET LOCKA-----%s' %(self.name,time.ctime()))
            # time.sleep(1)
            RLock.acquire()
            print('I am %s GET LOCKB-----%s' %(self.name,time.ctime()))
            RLock.release()
            # time.sleep(2)
    
            RLock.release()
    
    RLock = threading.RLock()
    # LockB = threading.Lock()
    
    for i in range(10):
        t = MyThread()
        t.start()

    信号量

    import threading
    import time
    
    semaphore = threading.Semaphore(10)
    
    def foo():
        semaphore.acquire()
        print('OK')
        time.sleep(1)
        semaphore.release()
    
    for i in range(100):
        t = threading.Thread(target=foo,args=())
        t.start()

    event对象

    import threading,time
    
    event = threading.Event() # 默认isSet()=False,加.wait()阻塞
    
    def foo():
        while not event.is_set():
            print('wait.....')
            event.wait(2)
    
            print('Connect to redis server')
    
    for i in range(5):
        t = threading.Thread(target=foo,args=())
        t.start()
    
    print('attempt to start redis server')
    time.sleep(10)
    event.set()     # 主线程给子线程set()

    队列

    队列:基于锁实现的,用于多线程,保证线程安全的一种数据结构

    ############################################ FIFO先进先出模型
    import queue
    
    q = queue.Queue(3)  # 参数为队列最大数,不加参数默认无限大
    print(q)
    
    q.put(11)
    q.put('hello')
    # q.put(3.14)
    q.put(555,block = False)  # 阻塞,如果队列满,报错
    # q.put(555)  # 大于最大值,会阻塞,等待队列中数据被拿走后在进队列
    
    print(q.get())
    print(q.get())
    print(q.get())
    # print(q.get(block = False))  # 阻塞,如果队空,报错
    
    # print(q.get())   # 队列空后,会阻塞,等待队列被加入
    ############################################ LIFO后进先出模型
    import queue
    
    q = queue.LifoQueue()
    
    q.put(11)
    q.put(22)
    q.put(33)
    
    while not q.empty():
        print(q.get())
    ############################################ priority优先级模型
    import queue
    
    q = queue.PriorityQueue()
    
    q.put([1,'11111'])  # []表示一个序列数据类型,也可全部换成()
    q.put([1,'00000'])  # 优先级相同,优先级按照ascii码顺序
    q.put([5,'55555'])
    q.put([3,'33333'])
    q.put([4,'44444'])
    q.put([2,'22222'])
    
    while not q.empty():
        print(q.get())

    队列的两个方法.join()和.task_done()  

    两个方法必须配合使用

    .join()方法阻塞进程,知道所有任务完成

    .task_done()方法在每次队列执行完后必须添加

    import queue,threading
    
    q = queue.Queue()
    
    def foo():
        q.put(111)
        q.put(222)
        q.put(333)
        q.join()
        print('ok')
    
    def bar():
        print(q.get())
        q.task_done()   # 每取一个队列,必须执行一条task_done()
        print(q.get())
        q.task_done()
        print(q.get())
        q.task_done()
    
    t1 = threading.Thread(target=foo,args=())
    t1.start()
    
    t2 = threading.Thread(target=bar,args=())
    t2.start()
    '''
    队列实例:生产者消费者模型
    生产者:创建数据的模型
    消费者:获取数据的模型

    优点:
    1、解耦合
    2、实现并发
    '''
    import queue,threading,time
    import random
    
    q=queue.Queue(50)
    
    def Producer(id):
        count=1
        while count<10: # 一次可做10个包子
            if q.qsize()<20:    # 当包子数小于20个,厨师才做
                s=random.randint(1,100)   # 包子代号
                q.put(s)
                print(id+" has made baozi %s"%s)
                time.sleep(1)   # 此IO可切线程,每做一个包子换另一个厨师,直到做够最小包子数
                count+=1
    
    def Consumer(id):
    
        while True:
             s=q.get()  # 取包子,s是代号
             print("Consumer "+id+" has eat %s"%s)
             time.sleep(2)
    
    
    for i in range(10):
        t1=threading.Thread(target=Producer,args=(str(i),))
        t1.start()
    
    for i in range(10):
    
        t=threading.Thread(target=Consumer,args=(str(i),))
        t.start()



  • 相关阅读:
    圣诞节快乐 | 圣诞特效来了!!
    前端特效demo | 值得收藏的6个 HTML5 Canvas 实用案例
    前端特效demo | 一起围观 10 种创意时钟
    即学即用,轻松搞定这些选择器!(下)
    架构师究竟要不要写代码?
    偷懒秘诀之变量篇
    弹幕,是怎样练成的?
    [C++]模板类和模板函数
    [C++]typedef用法
    [面试]CVTE 2019提前批 Windows应用开发一面
  • 原文地址:https://www.cnblogs.com/lucaq/p/7225166.html
Copyright © 2020-2023  润新知