• 线程


    线程基础知识
    import os
    import time
    from threading import Thread
    # 多线程并发
    # def func(a,b):
    #     global g
    #     g = 0
    #     print(g,os.getpid())
    #
    # g = 100
    # t_lst = []
    # for i in range(10):
    #     t = Thread(target=func,args=(i,5))
    #     t.start()
    #     t_lst.append(t)
    # for t in  t_lst : t.join()
    # print(g)
    # class MyTread(Thread):
    #     def __init__(self,arg):
    #         super().__init__()
    #         self.arg = arg
    #     def run(self):
    #         time.sleep(1)
    #         print(self.arg)
    #
    # t = MyTread(10)
    # t.start()
    
    # 进程 是 最小的 内存分配单位
    # 线程 是 操作系统调度的最小单位
    # 线程直接被CPU执行,进程内至少含有一个线程,也可以开启多个线程
        # 开启一个线程所需要的时间要远远小于开启一个进程
        # 多个线程内部有自己的数据栈,数据不共享
        # 全局变量在多个线程之间是共享的
    # GIL锁(即全局解释器锁)
    # 在Cpython解释器下的python程序 在同一时刻 多个线程中只能有一个线程被CPU执行
    # 高CPU : 计算类 --- 高CPU利用率
    # 高IO  : 爬取网页 200个网页
            # qq聊天   send recv
            # 处理日志文件 读文件
            # 处理web请求
            # 读数据库 写数据库
    
    import time
    from threading import Thread
    from multiprocessing import Process
    def func(n):
        n + 1
    
    if __name__ == '__main__':
        start = time.time()
        t_lst = []
        for i in range(100):
            t = Thread(target=func,args=(i,))
            t.start()
            t_lst.append(t)
        for t in t_lst:t.join()
        t1 = time.time() - start
    
        start = time.time()
        t_lst = []
        for i in range(100):
            t = Process(target=func, args=(i,))
            t.start()
            t_lst.append(t)
        for t in t_lst: t.join()
        t2 = time.time() - start
        print(t1,t2)
    线程基础知识
    import time
    import threading
    
    def wahaha(n):
        time.sleep(0.5)
        print(n,threading.current_thread(),threading.get_ident())
    
    for i in  range(10):
        threading.Thread(target=wahaha,args=(i,)).start()
    print(threading.active_count())    # 10
    print(threading.current_thread())
    print(threading.enumerate())
    线程模块中的其他方法

     多线程聊天程序

    import socket
    from threading import Thread
    
    def chat(conn):
        conn.send(b'hello')
        msg = conn.recv(1024).decode('utf-8')
        print(msg)
        conn.close()
    
    sk = socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.listen()
    while True:
        conn,addr = sk.accept()
        Thread(target=chat,args = (conn,)).start()
    sk.close()
    多线程聊天服务端
    import socket
    
    sk = socket.socket()
    sk.connect(('127.0.0.1',8080))
    
    msg = sk.recv(1024)
    print(msg)
    inp = input('>>> ').encode('utf-8')
    sk.send(inp)
    sk.close()
    多线程聊天客户端

     守护线程

    import time
    from threading import Thread
    def func1():
        while True:
            print('*'*10)
            time.sleep(1)
    def func2():
        print('in func2')
        time.sleep(5)
    
    t = Thread(target=func1,)
    t.daemon = True
    t.start()
    t2 = Thread(target=func2,)
    t2.start()
    t2.join()
    print('主线程')
    
    # 守护进程随着主进程代码的执行结束而结束
    # 守护线程会在主线程结束之后等待其他子线程的结束才结束
    
    # 主进程在执行完自己的代码之后不会立即结束 而是等待子进程结束之后 回收子进程的资源
    # import time
    # from multiprocessing import Process
    # def func():
    #     time.sleep(5)
    #
    # if __name__ == '__main__':
    #         Process(target=func).start()
    守护线程
    import time
    from threading import Lock,Thread
    # Lock 互斥锁
    # def func(lock):
    #     global n
    #     lock.acquire()
    #     temp = n
    #     time.sleep(0.2)
    #     n = temp - 1
    #     lock.release()
    #
    # n = 10
    # t_lst = []
    # lock = Lock()
    # for i in range(10):
    #     t = Thread(target=func,args=(lock,))
    #     t.start()
    #     t_lst.append(t)
    
    # for t in  t_lst: t.join()
    # print(n)
    
    # 科学家吃面
    
    # noodle_lock  = Lock()
    # fork_lock = Lock()
    # def eat1(name):
    #     noodle_lock.acquire()
    #     print('%s拿到面条啦'%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('%s拿到面条啦'%name)
    #     print('%s吃面'%name)
    #     noodle_lock.release()
    #     fork_lock.release()
    #
    # Thread(target=eat1,args=('alex',)).start()
    # Thread(target=eat2,args=('Egon',)).start()
    # Thread(target=eat1,args=('bossjin',)).start()
    # Thread(target=eat2,args=('nezha',)).start()
    
    from threading import RLock   # 递归锁
    fork_lock = noodle_lock  = RLock()   # 一个钥匙串上的两把钥匙
    def eat1(name):
        noodle_lock.acquire()            # 一把钥匙
        print('%s拿到面条啦'%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('%s拿到面条啦'%name)
        print('%s吃面'%name)
        noodle_lock.release()
        fork_lock.release()
    
    Thread(target=eat1,args=('alex',)).start()
    Thread(target=eat2,args=('Egon',)).start()
    Thread(target=eat1,args=('bossjin',)).start()
    Thread(target=eat2,args=('nezha',)).start()
    线程锁

    线程的信号量

    import time
    from threading import Semaphore,Thread
    def func(sem,a,b):
        sem.acquire()
        time.sleep(1)
        print(a+b)
        sem.release()
    
    sem = Semaphore(4)
    for i in range(10):
        t = Thread(target=func,args=(sem,i,i+5))
        t.start()
    信号量线程类似于进程

    线程的事件

    # 事件被创建的时候
    # False状态
        # wait() 阻塞
    # True状态
        # wait() 非阻塞
    # clear 设置状态为False
    # set  设置状态为True
    
    
    
    #  数据库 - 文件夹
    #  文件夹里有好多excel表格
        # 1.能够更方便的对数据进行增删改查
        # 2.安全访问的机制
    
    
    #  起两个线程
    #  第一个线程 : 连接数据库
            # 等待一个信号 告诉我我们之间的网络是通的
            # 连接数据库
    #  第二个线程 : 检测与数据库之间的网络是否连通
            # time.sleep(0,2) 2
            # 将事件的状态设置为True
    import time
    import random
    from threading import Thread,Event
    def connect_db(e):
        count = 0
        while count < 3:
            e.wait(0.5)   # 状态为False的时候,我只等待1s就结束
            if e.is_set() == True:
                print('连接数据库')
                break
            else:
                count += 1
                print('第%s次连接失败'%count)
        else:
            raise TimeoutError('数据库连接超时')
    
    def check_web(e):
        time.sleep(random.randint(0,3))
        e.set()
    
    e = Event()
    t1 = Thread(target=connect_db,args=(e,))
    t2 = Thread(target=check_web,args=(e,))
    t1.start()
    t2.start()
    线程事件类似于进程
    # 条件
    from threading import Condition
    
    # 条件
    #
    # acquire release
    # 一个条件被创建之初 默认有一个False状态
    # False状态 会影响wait一直处于等待状态
    # notify(int数据类型)  造钥匙
    from threading import Thread,Condition
    def func(con,i):
        con.acquire()
        con.wait() # 等钥匙
        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()
    线程的条件(新内容)

    .

    定时器

    import time
    from threading import Timer
    def func():
        print('时间同步')   #1-3
    
    while True:
        t = Timer(5,func).start()   # 非阻塞的
        time.sleep(5)
    定时器
    # queue
    import queue
    
    q = queue.Queue()  # 队列 先进先出
    # q.put()
    # q.get()
    # q.put_nowait()
    # q.get_nowait()
    
    # q = queue.LifoQueue()  # 栈 先进后出
    # q.put(1)
    # q.put(2)
    # q.put(3)
    # print(q.get())
    # print(q.get())
    
    q = queue.PriorityQueue()  # 优先级队列
    q.put((20,'a'))
    q.put((10,'b'))
    q.put((30,'c'))
    q.put((-5,'d'))
    q.put((1,'?'))
    print(q.get())
    队列
    import time
    from concurrent.futures import ThreadPoolExecutor
    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个数*5
    for i in  range(20):
        tpool.submit(func,i).add_done_callback(call_back)
    
    
    # tpool.map(func,range(20))  # 拿不到返回值
    # t_lst = []
    # for i in  range(20):
    #     t = tpool.submit(func,i)
    #     t_lst.append(t)
    # tpool.shutdown()  # close+join    #
    # print('主线程')
    # for t in t_lst:print('***',t.result())
    
    # ftp
    # 并发编程
    线程池

    小结

    线程
    # 线程是进程中的执行单位
    # 线程是cpu执行的最小单位
    # 线城之间资源共享
    # 线程的开启和关闭以及切换的时间开销远远小于进程
    # 线程本身可以在同一时间使用多个cpu
    # python 与 线程
    # Cpython解释器在解释代码过程中容易产生数据不安全的问题
    # GIL 全局解释器锁 锁的是线程
    # threading

  • 相关阅读:
    设计模式之单例模式(Singleton)
    ASP.Net WebForm温故知新学习笔记:二、ViewState与UpdatePanel探秘
    ASP.Net WebForm温故知新学习笔记:一、aspx与服务器控件探秘
    [学习笔记] $Maximum$ $Minimum$ $identity$
    BZOJ 2159: Crash 的文明世界(组合数学+第二类斯特林数+树形dp)
    BZOJ 3083: 遥远的国度 (树剖+线段树)
    LUOGU P4560 [IOI2014]Wall 砖墙 (线段树)
    牛客网 NOIP赛前集训营-普及组(第四场)C--部分和 (高维前缀和)
    LUOGU P1501 [国家集训队]Tree II (lct)
    LUOGU P3690 【模板】Link Cut Tree (lct)
  • 原文地址:https://www.cnblogs.com/cangshuchirou/p/8671632.html
Copyright © 2020-2023  润新知