python-10日目のまとめ(スレッド、プロセス、およびスレッド)

24283 ワード

Pythonスレッド
Threadingは、アプリケーションで動作する最小ユニットであるスレッド関連の動作を提供するために使用されます.
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import time
  
def show(arg):
    time.sleep(1)
    print 'thread'+str(arg)
  
for i in range(10):
    t = threading.Thread(target=show, args=(i,))
    t.start()
  
print 'main thread stop'

上記のコードは10個の「フロント」スレッドを作成し、コントローラはCPUに渡し、CPUは指定したアルゴリズムに従ってスケジューリングし、スライスして命令を実行する.
その他の方法:
  • startスレッド準備完了、CPUスケジューリング待ち
  • setNameスレッドの名前
  • getNameスレッド名
  • を取得
  • setDaemonはバックグラウンドスレッドまたはフロントスレッド(デフォルト)に設定バックグラウンドスレッドであれば、メインスレッド実行中、バックグラウンドスレッドも行われており、メインスレッド実行が完了すると、バックグラウンドスレッドは成功するかどうかにかかわらず、フロントスレッドであれば停止し、メインスレッド実行中、フロントスレッドも行う、メインスレッドの実行が完了した後、フロントスレッドの実行が完了するのを待って、プログラムは
  • を停止する.
  • joinは、各スレッドを1つずつ実行する、実行が完了した後も実行を継続し、この方法によりマルチスレッドが無意味になる
  • .
  • runスレッドがcpuによってスケジューリングされた後にThreadクラスオブジェクトのrunメソッド
  • を実行する.
    ワイヤロック
    スレッド間ではランダムスケジューリングが行われているため、各スレッドはn個の実行のみを実行した後、CPUは他のスレッドを実行することができる.したがって、次のような問題が発生する可能性があります.
    ロックは使用されていません:
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import threading
    import time
    
    gl_num = 0
    
    def show(arg):
        global gl_num
        time.sleep(1)
        gl_num +=1
        print gl_num
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    
    print 'main thread stop'

    ロックの使用:
    #!/usr/bin/env python
    #coding:utf-8
       
    import threading
    import time
       
    gl_num = 0
       
    lock = threading.RLock()
       
    def Func():
        lock.acquire()
        global gl_num
        gl_num +=1
        time.sleep(1)
        print gl_num
        lock.release()
           
    for i in range(10):
        t = threading.Thread(target=Func)
        t.start()

    event
    pythonスレッドのイベントは、主スレッドが他のスレッドの実行を制御するために使用され、イベントは主に3つの方法set、wait、clearを提供します.
    イベント処理のメカニズム:グローバルに「Flag」を定義し、「Flag」の値がFalseの場合、プログラムがeventを実行する.waitメソッドはブロックされ、「Flag」の値がTrueの場合event.waitメソッドではブロックされません.
  • clear:FlagをFalse
  • に設定
  • set:「Flag」をTrue
  • に設定
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
     
    import threading
     
     
    def do(event):
        print 'start'
        event.wait()
        print 'execute'
     
     
    event_obj = threading.Event()
    for i in range(10):
        t = threading.Thread(target=do, args=(event_obj,))
        t.start()
     
    event_obj.clear()
    inp = raw_input('input:')
    if inp == 'true':
        event_obj.set()

    Pythonプロセス
     1 from multiprocessing import Process
     2 import threading
     3 import time
     4   
     5 def foo(i):
     6     print 'say hi',i
     7   
     8 for i in range(10):
     9     p = Process(target=foo,args=(i,))
    10     p.start()

    注:プロセス間のデータはそれぞれ1部持つ必要があるため、プロセスを作成するのに非常に大きなコストがかかります.
    プロセスデータ共有
    プロセスはそれぞれ1部のデータを持っており、デフォルトではデータを共有できません.
    #!/usr/bin/env python
    #coding:utf-8
     
    from multiprocessing import Process
    from multiprocessing import Manager
     
    import time
     
    li = []
     
    def foo(i):
        li.append(i)
        print 'say hi',li
      
    for i in range(10):
        p = Process(target=foo,args=(i,))
        p.start()
         
    print 'ending',li
    
               


     1 #   ,Array
     2 from multiprocessing import Process,Array
     3 temp = Array('i', [11,22,33,44]) #   i C        ,        
     4  
     5 def Foo(i):
     6     temp[i] = 100+i
     7     for item in temp:
     8         print i,'----->',item
     9  
    10 for i in range(2):
    11     p = Process(target=Foo,args=(i,))
    12     p.start()
    13  
    14 #   :manage.dict()    
    15 from multiprocessing import Process,Manager
    16  
    17 manage = Manager()
    18 dic = manage.dict()
    19  
    20 def Foo(i):
    21     dic[i] = 100+i
    22     print dic.values()
    23  
    24 for i in range(2):
    25     p = Process(target=Foo,args=(i,))
    26     p.start()
    27     p.join()

     
    'c': ctypes.c_char,  'u': ctypes.c_wchar,
    'b': ctypes.c_byte,  'B': ctypes.c_ubyte,
    'h': ctypes.c_short, 'H': ctypes.c_ushort,
     'i': ctypes.c_int,   'I': ctypes.c_uint,
     'l': ctypes.c_long,  'L': ctypes.c_ulong,
     'f': ctypes.c_float, 'd': ctypes.c_double
    
         

    プロセスの作成時(非使用時)、共有データはサブプロセスに取得され、プロセスで実行が完了したら元の値に割り当てられます.
    プロセスロックの例:
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from multiprocessing import Process, Array, RLock
    
    def Foo(lock,temp,i):
        """
          0   100
        """
        lock.acquire()
        temp[0] = 100+i
        for item in temp:
            print i,'----->',item
        lock.release()
    
    lock = RLock()
    temp = Array('i', [11, 22, 33, 44])
    
    for i in range(20):
        p = Process(target=Foo,args=(lock,temp,i,))
        p.start()
    

    プロセスプール
    プロセスプール内でプロセスシーケンスを維持し、使用するとプロセスプールにプロセスを取得します.プロセスプールシーケンスに使用可能なプロセスがない場合、プロセスプールに使用可能なプロセスがあるまでプログラムは待機します.
    プロセスプールには、次の2つの方法があります.
  • apply
  • apply_async
  •  1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 from  multiprocessing import Process,Pool
     4 import time
     5   
     6 def Foo(i):
     7     time.sleep(2)
     8     return i+100
     9   
    10 def Bar(arg):
    11     print arg
    12   
    13 pool = Pool(5)
    14 #print pool.apply(Foo,(1,))
    15 #print pool.apply_async(func =Foo, args=(1,)).get()
    16   
    17 for i in range(10):
    18     pool.apply_async(func=Foo, args=(i,),callback=Bar)
    19   
    20 print 'end'
    21 pool.close()
    22 pool.join()#              ,    ,        。

    きょうてい
    スレッドとプロセスの操作はプログラムによってシステムインタフェースをトリガし、最後の実行者はシステムである.コラボレーションの操作はプログラマーです.
    コパスの存在意義:マルチスレッドアプリケーションに対して、CPUはスライス方式でスレッド間の実行を切り替え、スレッドの切り替えに時間がかかる(保存状態、次回継続).コンカレントでは、1つのスレッドのみを使用し、1つのスレッドにコードブロックの実行順序を指定します.
    コンシステントの適用シーン:プログラムにCPUを必要としない操作が大量に存在する場合(IO)、コンシステントに適用する.
    greenlet
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
     
     
    from greenlet import greenlet
     
     
    def test1():
        print 12
        gr2.switch()
        print 34
        gr2.switch()
     
     
    def test2():
        print 56
        gr1.switch()
        print 78
     
    gr1 = greenlet(test1)
    gr2 = greenlet(test2)
    gr1.switch()

    gevent
    import gevent
     
    def foo():
        print('Running in foo')
        gevent.sleep(0)
        print('Explicit context switch to foo again')
     
    def bar():
        print('Explicit context to bar')
        gevent.sleep(0)
        print('Implicit context switch back to bar')
     
    gevent.joinall([
        gevent.spawn(foo),
        gevent.spawn(bar),
    ])

    IO操作の自動切替に遭遇した場合:
    from gevent import monkey; monkey.patch_all()
    import gevent
    import urllib2
    
    def f(url):
        print('GET: %s' % url)
        resp = urllib2.urlopen(url)
        data = resp.read()
        print('%d bytes received from %s.' % (len(data), url))
    
    gevent.joinall([
            gevent.spawn(f, 'https://www.python.org/'),
            gevent.spawn(f, 'https://www.yahoo.com/'),
            gevent.spawn(f, 'https://github.com/'),
    ])