zoukankan      html  css  js  c++  java
  • 线程

    参考链接:  https://www.cnblogs.com/Eva-J/articles/8306047.html

    threading

    单线程

    import time
    from threading import Thread
    
    
    def func(n):
        time.sleep(1)
        print(n)
    
    
    if __name__ == "__main__":
        
        # 创建一个子线程
        t = Thread(target=func, args=(1,))
        t.start()

    多线程

     主线程会等子线程执行完毕后再结束

    import time
    from threading import Thread
    
    # 多线程并发
    
    def func(n):
        time.sleep(5)
        print('我是子线程',n)
    
    
    for i in range(10):
    
        # 主线程会等子线程执行完毕后再结束
        t = Thread(target=func, args=(i,))
        t.start()
        print('我是主线程')

    类方法使用线程

    import time
    from threading import Thread
    
    # 多线程并发
    
    class MyTread(Thread):
        # 要使用新属性时需要调用父类的init
        def __init__(self,args):
            super().__init__()
            self.args = args
    
        # 一定要创建一个类方法
        def run(self):
            time.sleep(1)
            print(self.args)
    
    
    t = MyTread(10)
    t.start()

    ps:

    #进程是最小的内存分配单位。

    #线程是 操作系统调度的最小单位。
    #线程被CPU执行了。
    #进程内至少含有一个线程。
    #进程中可以开启多个线程。
    #开启一个线程所需要的时间要远远小于开启一个进程。
    #多个线程内部有自己的数据栈,数据不共享。
    #全局变量在多个线程之间是共享的。
    #在Cpython解释器下的python程序 在同一时刻 多个线程中只能有一个线程被CPU执行。GIL锁(全局解释器锁)
    #高CPU :计算类——高CPU利用率。
    #高IO  :爬取网页 200个网页
    #qq聊天  send  recv  处理日志文件 读文件 处理web请求 读数据库

    全局变量在多线程中是共享的 

    import time
    import os
    from threading import Thread
    
    # 多线程并发
    
    def func(a, b):
        global g
        g = 0
    
        n = a + b
    
    
    # 调用这个子线程之后,由于他声明了全部变量 所以这个g = 0
    g = 100
    lst = []
    
    for i in range(1):
        # 开启一个子线程
        t = Thread(target=func, args=(i, 5))
        t.start()
    
        # 我这里只是为了取一个循环次数
        lst.append(t)
    
    for t in lst:
        # 等子线程 执行完之后再执行 主线程
        t.join()
        
        #全局变量在线程之间是共享的
        print('主线程', g)

    多进程和多线程时间对比

    这差距不是一般的大呀!!!!

    线程socket可以连接多个client

     client

    线程模块中的其他方法

    # 查看当前活跃线程数加上主线程  #10 +
    print(threading.active_count())

    # 查看是否属于主线程还是子线程
    print(threading.current_thread())

    # 显示所有线程名和id
    print(threading.enumerate())
    # get_ident 是查看线程id
    print(threading.get_ident())

    import time
    import os
    from threading import Thread
    import threading
    
    # 多线程并发
    
    def func(n):
        time.sleep(0.5)
    
        # 查看是否属于主线程还是子线程
        print(i,threading.current_thread())
    
        # get_ident 是查看线程id
        print(threading.get_ident())
    
    for i in range(10):
        t = threading.Thread(target=func,args=(i,))
        t.start()
    
    # 查看当前活跃线程数加上主线程  #10 +
    print(threading.active_count())
    
    # 查看是否属于主线程还是子线程
    print(threading.current_thread())
    
    # 显示所有线程名和id
    print(threading.enumerate())

    守护线程

    #守护进程随着主线程程代码的执行结束而结束。
    #守护线程会在主线程执行完之后等待其他子线程的结束才结束。
    #主线程在执行完自己的代码之后不会立即结束 而是等待子线程结束之后 回收子线程的资源。

    import time
    from threading import Thread
    
    def func1():
        while 1 :
            time.sleep(1)
            print("33[31m ******我还活着呢33[0m")
    
    def func2():
        time.sleep(10)
        print("我他吗是 func2")
    
    if __name__ =='__main__':
        t1 = Thread(target=func1)
    
        # 定义一个守护线程(主线程结束之后 等待其他子线程的结束才结束 守护线程随之结束)
        t1.daemon = True
        t1.start()
    
        t2 = Thread(target=func2)
        t2.start()
        print("主线程")

    线程锁(互斥锁)

    数据不安全问题:

     

    #10个线程同时开起来 同时去拿n = 10,拿回来之后隔了0.2秒才回来。
    #在拿回来的过程当中别人都去拿,都拿的10,赋值回去了就是9
    from threading import Lock, Thread
    import time
    
    
    # 死锁问题
    def func():
        global n
    
        temp = n
        time.sleep(0.1)
        n = temp - 1
    
    n = 10
    lst = []
    
    for i in range(10):
        t = Thread(target=func, args=())
        t.start()
        lst.append(t)
    
    # 等待子线程执行完毕之后我再执行
    t.join()
    for i in lst:
        print(n)

    0.2秒钟做的事情 

    解决数据不安全问题

    加锁

    from threading import Lock
    from threading import Thread
    import time
    
    
    # 死锁问题
    def func(lock):
        global n
    
        # 拿钥匙 保证数据安全
        lock.acquire()
    
        temp = n
        time.sleep(0.1)
        n = temp - 1
    
        # 还钥匙 保证数据安全
        lock.release()
    
    
    n = 10
    lst = []
    lock = Lock()
    for i in range(10):
    
        t = Thread(target=func, args=(lock,))
        t.start()
        lst.append(t)
    
    # 等待子线程执行完毕之后我再执行
    t.join()
    for i in lst:
        print(n)

    科学家吃面现象(死锁问题)

    只有一把钥匙,如果你要是同时,不管在一个进程里,还是在多个进程之间,你想拿多个钥匙就不行了。

    from threading import Lock
    from threading import Thread
    import time
    
    # 定义一个面条锁
    noodle_lock = Lock()
    
    # 定义一个叉子锁
    fork_lock = Lock()
    
    
    def eat1(name):
        # 加面条锁
        noodle_lock.acquire()
        print("33[31m %s 拿到面条了33[0m" % name)
    
        # 加勺子锁
        fork_lock.acquire()
        print('%s 拿到叉子了' % name)
        print('%s 吃面' % name)
    
        # 释放勺子锁
        fork_lock.release()
    
        # 释放面条锁
        noodle_lock.release()
    
    
    def eat2(name):
        # 加勺子锁
        fork_lock.acquire()
        print('%s 拿到叉子了' % name)
        
        # 在停顿的时候黄埔也过去拿了面条,由于没有钥匙了 所以就停住了
        time.sleep(1)
    
        # 加面条锁
        noodle_lock.acquire()
        print("33[31m %s 拿到面条了33[0m" % name)
        print('%s 吃面' % name)
    
        # 释放勺子锁
        fork_lock.release()
    
        # 释放面条锁
        noodle_lock.release()
    
    
    Thread(target=eat1, args=('Riven',)).start()
    
    Thread(target=eat2, args=('Mark',)).start()
    
    Thread(target=eat1, args=('黄埔',)).start()
    
    Thread(target=eat2, args=('汨汨',)).start()

    解决死锁问题(递归锁

    同一个线程里拿多少次钥匙都可以,但又一个人拿到了这一串钥匙别的人就再也拿不到了。

     

    from threading import RLock
    
    # RLock = 一串钥匙
    rlock = RLock()
    
    rlock.acquire()
    rlock.acquire()
    rlock.acquire()
    rlock.acquire()
    rlock.acquire()
    rlock.acquire()
    rlock.acquire()
    rlock.acquire()
    rlock.acquire()
    
    print('123')
    from threading import Thread
    from threading import RLock
    import time
    
    
    
    # 一个钥匙串 2 把钥匙
    fork_lock = noodle_lock = RLock()
    
    
    def eat1(name):
        # 我拿了一把钥匙,就一串钥匙在我手上
        noodle_lock.acquire()
        print("33[31m %s 拿到面条了33[0m" % name)
    
    
        fork_lock.acquire()
        print('%s 拿到叉子了' % name)
        print('%s 吃面' % name)
    
        # 等我把这一串钥匙都还了,下个人才能进来 就不会出现阻塞现象
        fork_lock.release()
    
        # 等我把这一串钥匙都还了,下个人才能进来 就不会出现阻塞现象
        noodle_lock.release()
    
    
    def eat2(name):
        # # 我拿了一把钥匙,就一串钥匙在我手上
        fork_lock.acquire()
        print('%s 拿到叉子了' % name)
    
        time.sleep(1)
    
        noodle_lock.acquire()
        print("33[31m %s 拿到面条了33[0m" % name)
        print('%s 吃面' % name)
    
        # 等我把这一串钥匙都还了,下个人才能进来 就不会出现阻塞现象
        fork_lock.release()
    
        # 等我把这一串钥匙都还了,下个人才能进来 就不会出现阻塞现象
        noodle_lock.release()
    
    
    Thread(target=eat1, args=('Riven',)).start()
    
    Thread(target=eat2, args=('Mark',)).start()
    
    Thread(target=eat1, args=('黄埔',)).start()
    
    Thread(target=eat2, args=('汨汨',)).start()

    信号量(Semaphore

     

    事件

    False状态

    Wait()         false时阻塞

    Wait()         ture时非阻塞

    Clear                   False状态修改为False

    Set                       False状态修改为True

    例子

    (连接数据库,检测数据库的可连接情况)

    数据库---文件夹:

    1.能够更方便的对数据进行增删改查

    2.安全访问的机制

     

     

    条件(Condition)

    一个条件被创建之初默认有一个False状态。

    False 状态会影响wait一直处于等待状态。

    notifyint数据类型)制造几把钥匙。有几把钥匙就执行几次

    from threading import Thread
    from threading import Condition
    
    
    def func(con, i):
        con.acquire()
    
        # 等钥匙,也就是说你有几把钥匙,就执行几次
        con.wait()
        print("33[31m 在第 %s 个循环里33[0m" % i)
    
        con.release()
    
    
    con = Condition()
    
    for i in range(10):
        Thread(target=func, args=(con, i)).start()
    
    while 1:
        num = int(input('>>>>'))
    
        con.acquire()
        con.notify(num)  # 造钥匙
        con.release()

    线程定时器(Timer)

    import time
    from threading import Timer
    
    
    def func():
        print('时间同步')
    
    
    while True:
        t = Timer(5, func).start()
        # 需要定义一个延时时间
        time.sleep(3)

    队列

    # 进程队列 先进先出

    import queue
    
    # 进程队列 先进先出
    q = queue.Queue()
    
    # 先进先出
    # q.put(1)
    # q.put(2)
    
    q.put_nowait(1)
    q.put_nowait(2)
    
    # get_nowait 不会阻塞 会抛错
    print(q.get_nowait())
    print(q.get_nowait())
    print(q.get_nowait())
    
    # get 会阻塞
    # print(q.get())
    # print(q.get())

    栈 先进后出

    import queue
    
    # 栈 先进后出
    q = queue.LifoQueue()
    
    q.put(1)
    q.put(2)
    q.put(3)
    
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())

    优先级队列(按照值的大小进行排序 从小到大)

    import queue
    
    # 优先级队列(按照值的大小进行排序 从小到大)
    q = queue.PriorityQueue()
    
    q.put(20)
    q.put(50)
    q.put(25)
    q.put(40)
    
    print(q.get())
    print(q.get())
    print(q.get())
    print(q.get())

    线程池(ThreadPoolExecutor)

    import time
    from concurrent.futures import ThreadPoolExecutor
    
    
    def func(n):
        print(n)
        time.sleep(1)
        return n * 10
    
    
    t_lst = []
    
    # 定义一个线程池(默认 不要超过cup个数*5)
    tpool = ThreadPoolExecutor(max_workers=5)
    
    for i in range(20):
    
        # 传值(开启20个子线程)
        t = tpool.submit(func, i)
        t_lst.append(t)
    
    # 相当于 close + join
    tpool.shutdown()
    
    print("主线程")
    
    for t in t_lst:
        # t.result() 接受返回值
        print("33[31m ==== 33[0m", t.result())

    如果接受不到 返回值

    在自定义函数中接受返回值

  • 相关阅读:
    【IDEA插件】—— 代码量统计工具Statistic
    【Funny Things】001——QQ循环发送消息
    【jmeter测试范例】001——TCP测试
    【Jmeter源码解读】003——TCP采样器代码解析
    【Jmeter源码解读】002——程序入口类NewDriver.java
    Eclipse点击空格总是自动补全代码怎么办,如何自动补全代码,代码提示
    路径中关于斜杠/和反斜杠 的区别
    eclipse查看JDK源码
    Navicat premium如何使用Oracle的OCI
    斐波那契查找不再迷惑
  • 原文地址:https://www.cnblogs.com/Rivend/p/12040470.html
Copyright © 2011-2022 走看看