• 三十、全局解释器锁,线程池,条件,定时器,线程队列,信号量和事件(线程)


    一、线程池

    from concurrent.futures import ThreadPoolExecutor
    import time
    
    
    def func(n):
        time.sleep(2)
        print(n)
        return n * n
    
    
    def call_back(m):
        print("结果是:%s" % m.result())  # 拿到结果
    
    
    tpool = ThreadPoolExecutor(max_workers=5)  # 默认不要超过cpu个数+1
    # tpool.map(func,range(10))  # 使用map拿不到返回值
    # for i in range(10):
    #     t = tpool.submit(func, i).add_done_callback(call_back)  # 回调函数
    
    t_list = []
    for i in range(10):
        t = tpool.submit(func, i)  # 一次五个,异步执行
        t_list.append(t)
    # tpool.shutdown()  # 起到 close 和join 作用   阻塞,所有线程池执行完
    print("主线程:")
    for t in t_list: print("***", t.result())  # 拿到返回值"""

    二、全局解释器锁:gil

      全局锁:同一时刻只能有一个线程访问CPU,在Cpython中 在同一时刻 多个线程只能有一个被执行。

      原因:多个线程被CPU调度处理数据中,在解释型语言中系统没法识别,多个线程是否会在同一时刻访问相同数据,会出现不同CPU在同一时               刻,分别调用同一进程下多个线程,访问同一数据,进行增删改查,造成数据混乱,全局锁的出现就是为加强对数据的安全!

      疑问:既然有了全局锁为何数据还需要加锁?

       在全局变量中,多进程或者多线程去访问同一数据,当其中一个进程或者线程拿到数据,释放了全局锁,突然遇到阻塞,其他进程或者线程这              时候拿到也拿到相同数据,同时去执行,也会造成数据混乱。

      什么时候选择多进程和多线程:

    高CPU:计算类>>>>>>>高CPU利用率(多进程
    高IO:input 爬取网页 ,qq聊天,处理日志文件,读文件,处理web请求,读写数据库等等>>>>>>(多线程)

    三、线程(信号量和事件)

    1.多线程信号量:

    from threading import Semaphore, Thread
    import time
    
    
    def func(sem, a, b):
        time.sleep(1)
        sem.acquire()
        print(a + b)
        sem.release()
    
    
    sem = Semaphore(4)
    for i in range(10):
        t = Thread(target=func, args=(sem, i, i + 5))
        t.start()

    2.事件

    应用:连接数据库 ,检测数据库的可连接情况

    起两个线程:
    第一个线程:连接数据库
    等待一个信号 告诉我们之间的网络是通的
    第二个线程:检测与数据库之间的网络是否连通
    time。sleep(0,2) 2 将事件设置为True
    # 事件被创建的时候
    # false 状态 wait()阻塞
    # true 状态 wait()非阻塞
    # clear 设置状态为 False
    # set 设置状态为 True"""
    mport time, random
    from threading import Event, Thread
    
    
    def connect(e):
        count = 0
        while count < 3:
            e.wait(1)  # 状态为False 的时候,我只等待1s就结束
            if e.is_set() == True:
                print("连接数据库成功!")
                break
    
            else:
                count += 1
                print("第%d次连接失败" % count)
        else:
            raise TimeoutError("数据库连接异常")
    
    
    def check_web(e):
        time.sleep(random.randint(0, 3))
        e.set()
    
    
    e = Event()
    t1 = Thread(target=connect, args=(e,))
    t2 = Thread(target=check_web, args=(e,))
    t1.start()
    t2.start()
    数据库检测通讯应用

    四、条件

      Condition条件:更复杂锁
    提供 acquire release
    一个条件被创建之初,默认有一个False状态
    False状态 会影响wait 一直处于等待状态
    notify(int数据类型)制造几把钥匙,就能过去几个线程"""
    from threading import Condition, Thread
    
    
    def func(con, i):
        con.acquire()
        con.wait()  # 一直在等待钥匙,然后放行,有一把放一个,有10个放十个
        print("在第%s个循环里" % i)
        con.release()
    
    
    con = Condition()
    for i in range(10):
        Thread(target=func, args=(con, i,)).start()
    while True:
        num = int(input(">>>>>>>:"))
        con.acquire()
        con.notify(num)  # 造钥匙
        con.release()

    五、定时器

    from threading import Timer
    import time
    
    
    def func():
        print("时间同步")
    
    
    while True:
        t = Timer(5, func).start()  # 非阻塞
        time.sleep(5)
    
    # 每5秒执行一次

    六、线程队列

    import queue
    
    q = queue.Queue()
    q.put(1)
    q.put(2)
    # q.put_nowait()
    q.get()
    
    # q = queue.LifoQueue()  # 栈 先进后出
    # q.put(1)
    # q.put(2)
    # q.put(3)
    # print(q.get())
    # print(q.get())
    # print(q.get())
    
    q = queue.PriorityQueue()  # 优先级队列,谁的数小谁先出去
    q.put((20, "a"))
    q.put((10, "b"))
    q.put((30, "c"))
    q.put((1, "d"))
    print(q.get())

            

  • 相关阅读:
    memcached +mysql+php 例子
    PHP利用memcache缓存技术提高响应速度
    实现QQ第三方登录教程(php)
    php如何解决多线程同时读写一个文件的问题
    php数组函数常见的那些
    PHP 5种方式获取文件后缀名
    函数与方程
    函数图像习题
    高中数学中需要重点关注的函数和图像
    特殊分段函数的图像画法
  • 原文地址:https://www.cnblogs.com/wukai66/p/11358863.html
Copyright © 2020-2023  润新知