GILおよび協程

7588 ワード

GILおよび協程
一、GILグローバル解釈器ロック
  • デモ
  • '''
    python   :
        - Cpython c  
        - Jpython java
    
    1、GIL:      
        -   :              ,             ,  Cpython           。
    
        - GIL      ,          ,      
    
      :
    In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
    native threads from executing Python bytecodes at once. This lock is necessary mainly
    because CPython’s memory management is not thread-safe. (However, since the GIL
    exists, other features have grown to depend on the guarantees that it enforces.)
    
      : Cpython    ,            ,             ,         。
    
    
    GIL         :
    
          :
                   
          :
                 ,      ,      ,      ,      
    
            - IO   :    
            -      :    
    '''
    
    import time
    from threading import Thread, Lock
    lock = Lock()
    
    
    n = 100
    
    
    def task():
        lock.acquire()
        global n
        m = n
        time.sleep(1)
        n = m - 1
        lock.release()
    
    
    if __name__ == '__main__':
        list1 = []
    
    
        for line in range(10):
            t = Thread(target=task)
            t.start()
            list1.append(t)
    
        for t in list1:
            t.join()
    
        print(n)
  • リソースの検索
  • #    ,          
    # import gc
    
    # -       :
    # -   :     、CSDN、cnblogs、https://www.v2ex.com/
    # -   : Stack Overflow、github、  
    

    二、マルチスレッドを使用して効率を高める
  • from threading import Thread
    from multiprocessing import Process
    import time
    
    '''
    IO         
               
    
    IO     ,    4s
    
        -   :
            -          
            
        -   :
            -    :
                -   4    :16s
                
            -    :
                -   4    :16s +            
                
           ,    4s
        -   :
            -            
            
        -   :
               :
                -   4    :16s
                
               :
                -       :4s
                
            
    '''
    
    # def task1():
    #     #  1000000   += 1
    #     i = 10
    #     for line in range(1000000):
    #         i += 1
    #
    #
    # def task2():
    #     time.sleep(2)
    #
    #
    # if __name__ == '__main__':
    #
    #     # 1、     
    #     #        
    #     start_time = time.time()
    #     list1 = []
    #     for line in range(6):
    #         p = Process(target=task1)
    #         p.start()
    #         list1.append(p)
    #
    #     for p in list1:
    #         p.join()
    #
    #     end_time = time.time()
    #
    #     #    
    #     print(f'            :{end_time - start_time}')
    #     #          :1.4906916618347168
    #
    #     #   IO   
    #     start_time = time.time()
    #     list1 = []
    #     for line in range(6):
    #         p = Process(target=task2)
    #         p.start()
    #         list1.append(p)
    #
    #     for p in list1:
    #         p.join()
    #
    #     end_time = time.time()
    #
    #     #    
    #     print(f'   IO     :{end_time - start_time}')
    #
    #
    #
    #
    #     #2、     
    #     #       
    #     start_time = time.time()
    #     list1 = []
    #     for line in range(6):
    #         t = Thread(target=task1)
    #         t.start()
    #         list1.append(t)
    #
    #     for t in list1:
    #         t.join()
    #
    #     end_time = time.time()
    #     print(f'            :{end_time - start_time}')
    #     #          :0.41376233100891113
    #
    #
    #     #  IO   
    #     start_time = time.time()
    #     list1 = []
    #     for line in range(6):
    #         t = Thread(target=task2)
    #         t.start()
    #         list1.append(t)
    #
    #     for t in list1:
    #         t.join()
    #
    #     end_time = time.time()
    #     print(f'   IO       :{end_time - start_time}')
    #
    
    
    #        
    def task1():
        #   1000000  += 1
        i = 10
        for line in range(10000000):
            i += 1
    
    
    # IO     
    def task2():
        time.sleep(3)
    
    
    if __name__ == '__main__':
        # 1、     :
        #        
        start_time = time.time()
        list1 = []
        for line in range(6):
            p = Process(target=task1)
            p.start()
            list1.append(p)
    
        for p in list1:
            p.join()
        end_time = time.time()
        #     : 5.33872389793396
        print(f'         : {end_time - start_time}')
    
        #   IO   
        start_time = time.time()
        list1 = []
        for line in range(6):
            p = Process(target=task2)
            p.start()
            list1.append(p)
    
        for p in list1:
            p.join()
        end_time = time.time()
        #     : 4.517091751098633
        print(f'IO       : {end_time - start_time}')
    
    
        # 2、     :
        #        
        start_time = time.time()
        list1 = []
        for line in range(6):
            p = Thread(target=task1)
            p.start()
            list1.append(p)
    
        for p in list1:
            p.join()
        end_time = time.time()
        #     : 5.988943815231323
        print(f'         : {end_time - start_time}')
    
        #   IO   
        start_time = time.time()
        list1 = []
        for line in range(6):
            p = Thread(target=task2)
            p.start()
            list1.append(p)
    
        for p in list1:
            p.join()
        end_time = time.time()
        #     : 3.00256085395813
        print(f'IO     : {end_time - start_time}')
       
      :
       #  1 3   :              (        CPU)
       #  2 3   : IO           (        CPU)
    
       #       (    CPU)

    三、協程
  • デモ
  • ``python'''1、協程とは何ですか?プロセス:生産資源単位-スレッド:実行単位-協程:単一スレッドで同時実行
        -  IO       ,           
    
          ;        ,       YY     
    
          :   --->    --->            (        )
    
             :
            -     “  IO   +     ”        ,          IO  , CPU       

    '''
    import time
    def task1(): time.sleep(1)
    def task2(): time.sleep(3)
    def task3(): time.sleep(5)
    def task4(): time.sleep(7)
    def task5(): time.sleep(9)
    IO切替(gevent)+保存状態に遭遇
    from gevent import monkeyサルパッチ
    monkey.patch_all()#すべてのタスクにIO操作があるかどうかをリスニングfrom gevent import spawn#spawn(タスク)
    from gevent import joinall import time
    def task1(): print('start from task1....') time.sleep(1) print('end from task1....')
    def task2(): print('start from task2....') time.sleep(1) print('end from task2....')
    def task3(): print('start from task3....') time.sleep(1) print('end from task3....')
    if name == 'main':
    start_time = time.time()
    sp1 = spawn(task1)
    sp2 = spawn(task2)
    sp3 = spawn(task3)
    
    # sp1.start()
    # sp2.start()
    # sp3.start()
    # sp1.join()
    # sp2.join()
    # sp3.join()
    joinall([sp1, sp2, sp3])  #       
    
    end_time = time.time()
    
    print(f'    :{end_time - start_time}')

    start from task1....
    start from task2....
    start from task3....
    end from task1....
    end from task2....
    end from task3....
    消費時間:1.0085582733154297
    四、tcpサービス端の同時実現
  • コード
  • - client   
    import socket
    
    client = socket.socket()
    
    client.connect(
        ('127.0.0.1', 9000)
    )
    
    print('Client is run....')
    while True:
        msg = input('   >>:').encode('utf-8')
        client.send(msg)
    
        data = client.recv(1024)
        print(data)
    
    
    - sever   
    import socket
    from concurrent.futures import ThreadPoolExecutor
    
    server = socket.socket()
    
    server.bind(
        ('127.0.0.1', 9000)
    )
    
    server.listen(5)
    
    
    # 1.       
    def run(conn):
        while True:
            try:
                data = conn.recv(1024)
                if len(data) == 0:
                    break
                print(data.decode('utf-8'))
                conn.send('111'.encode('utf-8'))
    
            except Exception as e:
                break
    
        conn.close()
    
    
    if __name__ == '__main__':
        print('Server is run....')
        pool = ThreadPoolExecutor(50)
        while True:
            conn, addr = server.accept()
            print(addr)
            pool.submit(run, conn)