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())

    如果接受不到 返回值

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

  • 相关阅读:
    SharePoint 2013 APP 开发示例 (六)服务端跨域访问 Web Service (REST API)
    麦咖啡导致电脑不能上网
    SharePoint 2013 Central Admin 不能打开
    SharePoint 2013 APP 开发示例 (五)跨域访问 Web Service (REST API)
    SharePoint 2013 APP 开发示例 系列
    synthesize(合成) keyword in IOS
    Git Cmd
    简单的正则匹配
    Dropbox
    SQL Server Replication
  • 原文地址:https://www.cnblogs.com/Rivend/p/12040470.html
Copyright © 2011-2022 走看看