• 线程



    JoinableQueue的使用

    from multiprocessing import JoinableQueue, Queue
    
    q = JoinableQueue()
    q.put(1)
    q.put(2)
    
    print(q.get())
    q.task_done() # 告诉容器已经处理完了一个数据
    q.task_done() # 有几次就要调用几次
    q.join() # 也是一个阻塞函数 一直到队列中的数据被处理完毕(task_done的调用次数等于队列中数据数量)
    print('处理完毕')
    print(q.get())
    print(q.empty())
    JoinableQueue

    生产者消费者模型

    '''
    小明作为消费者 要吃热狗
    生产者 负责做热狗
    问题:
    小明不清楚对方会生产多少热狗
    '''
    
    from multiprocessing import Process, Queue, JoinableQueue
    import time, random
    
    
    # 生产者
    def make_hot_dog(q):
    for i in range(1, 6):
    time.sleep(random.randint(1, 3))
    print('生产者 生产了hot_dog%s' % i)
    q.put('hot_dog%s' % i)
    
    
    # 消费者
    def eat_hot_dog(q):
    while True:
    time.sleep(random.randint(1, 2))
    hot_dog = q.get()
    print('小明吃了%s' % hot_dog)
    q.task_done()
    
    
    if __name__ == '__main__':
    # 共享数据的队列
    q = JoinableQueue()
    # 生产者
    p1 = Process(target=make_hot_dog, args=(q,))
    p2 = Process(target=make_hot_dog, args=(q,))
    p1.start()
    p2.start()
    # 消费者
    c1 = Process(target=eat_hot_dog, args=(q,))
    c1.daemon = True
    c1.start()
    # 先要确定生产者已经不会再生产了
    p1.join()
    p2.join()
    print('生产已经结束了???')
    # 再确定队列中的数据都被处理完成
    q.join()
    print('小明已经全部吃完了。。。')
    c1.terminate()
    # 小明就不需要在吃了
    生产者消费者模型

    线程
    线程指的是一条流水线,整个执行过程中的总称,也是一个抽象概念
    线程是CPU的最小执行单位,是具体负责执行代码的

    进程是一个资源但闻,其中包括了该程序运行所需的所有子资源

    线程的特点:
    一个进程中至少包含一个线程,是由操作系统自动创建的,称之为主线程
    一个进程中可以有任意数量的线程
    创建线程的开销对比而言 要小的多
    同一个进程中的线程间数据是共享的(最主要的特点)
    如何使用:使用的方式与进程一致
    不同的是:创建线程的代码 可以写在任何位置

    from threading import Thread
    
    第一种 开启线程的方式 直接实例化Thread类
    def task():
    print('running .....')
    
    
    t = Thread(target=task)
    t.start()
    线程使用1
    2.继承Thread类 覆盖run方法
    class My(Thread):
    def run(self):
    print('running....')
    
    
    t = My()
    t.start()
    线程使用2

    开启线程速度比开启进程快很多
    主线程任务执行完毕后 进程不会立即结束 会等待所有子线程全部执行完毕
    在同一个进程 所有线程都是平等的 没有子父这么一说

    from threading import Thread
    
    import time
    
    
    def task():
    print('子线程 running 。。。')
    time.sleep(3)
    print('子线程over。。。')
    
    
    t = Thread(target=task)
    t.start()
    print('main over')
    线程效果

    线程与进程的区别
    一:数据是共享的
    二:创建进程 与创建线程的开销 线程比进程快大约是一百多倍
    线程安全也是通过锁来保证,锁的用法与进程中的锁一模一样

    import time
    
    from threading import Thread, Lock
    
    num = 10
    lock = Lock()
    
    
    def task():
    global num
    lock.acquire()
    a = num
    time.sleep(0.1)
    num = a - 1
    lock.release()
    
    
    ts = []
    for i in range(10):
    t = Thread(target=task)
    t.start()
    ts.append(t)
    
    for t in ts:
    t.join()
    
    print(num)
    线程的锁

    死锁:
    当你今后在开发一些高并发程序时 很有可能出现线程/进程安全问题
    解决方案只能加锁但是在使用锁时,很有可能出现死锁问题
    同一把锁调用了多次acquire 导致死锁问题(最low的死锁问题)
    有多把锁一个线程抢到一把锁,要完成任务必须同时抢到所有锁,这将导致死锁问题

    如何避免:
    1.能不加锁就不加锁
    2.如果一定要加 要保证锁只有一把

    线程对象的常用属性

    from threading import Thread
    
    # Thread对象常用属性
    t = Thread(name='一个线程')
    print(t.name)
    print(t.is_alive()) # 线程名称
    print(t.daemon)
    print(t.ident)
    
    # threading 模块中的常用属性
    import threading
    import os
    
    t = threading.current_thread() # 获取当前线程对象
    print(t)
    print(os.getpid())
    
    
    def task():
    print(threading.current_thread())
    
    
    print(threading.active_count()) # 获取目前活跃的线程数量
    Thread(target=task).start()
    print(threading.active_count()) # 正在运行中的线程数量
    ts = threading.enumerate() # 返回所有正在运行的线程对象
    print(ts)
    线程对象的常用属性

    信号量 可以控制同一时间 有多少线程可以并发的访问
    不是用来处理线程安全问题

    守护线程
    守护线程会在主线程结束后立即结束 即使任务没有完成
    主线程 会等待所有子线程全部完成后结束

    守护线程会在所有非守护线程结束后 结束
    主线 守护进程
    主线程要等待所有子线结束

    from threading import Thread, current_thread
    import time
    
    
    def task1():
    print('%s正在运行。。。' % current_thread().name)
    time.sleep(3)
    print('%s over 。。。' % current_thread().name)
    
    
    def task2():
    print('%s正在运行。。。' % current_thread().name)
    time.sleep(10)
    print('%s over 。。。' % current_thread().name)
    
    
    t1 = Thread(target=task1)
    t2 = Thread(target=task2)
    t1.start()
    t2.start()
    print('over')
    主线程等待所有子线程
  • 相关阅读:
    Devexpress之LayoutControl的使用及其控件布局设计
    C#入门笔记3 表达式及运算符2
    C#入门笔记3 表达式及运算符
    C#入门笔记2 变量
    C#入门笔记1
    Devexpress之GridControl显示序列号
    C++学习之重载运算符1
    解决"找不到该项目”无法删除该文件
    删除鼠标右键时“保存至360云盘”
    CSS基础知识——选择器
  • 原文地址:https://www.cnblogs.com/ShenJunHui6/p/10490122.html
Copyright © 2020-2023  润新知