python-10日目のまとめ(スレッド、プロセス、およびスレッド)
24283 ワード
Pythonスレッド
Threadingは、アプリケーションで動作する最小ユニットであるスレッド関連の動作を提供するために使用されます.
上記のコードは10個の「フロント」スレッドを作成し、コントローラはCPUに渡し、CPUは指定したアルゴリズムに従ってスケジューリングし、スライスして命令を実行する.
その他の方法: startスレッド準備完了、CPUスケジューリング待ち setNameスレッドの名前 getNameスレッド名 を取得 setDaemonはバックグラウンドスレッドまたはフロントスレッド(デフォルト)に設定バックグラウンドスレッドであれば、メインスレッド実行中、バックグラウンドスレッドも行われており、メインスレッド実行が完了すると、バックグラウンドスレッドは成功するかどうかにかかわらず、フロントスレッドであれば停止し、メインスレッド実行中、フロントスレッドも行う、メインスレッドの実行が完了した後、フロントスレッドの実行が完了するのを待って、プログラムは を停止する. joinは、各スレッドを1つずつ実行する、実行が完了した後も実行を継続し、この方法によりマルチスレッドが無意味になる . runスレッドがcpuによってスケジューリングされた後にThreadクラスオブジェクトのrunメソッド を実行する.
ワイヤロック
スレッド間ではランダムスケジューリングが行われているため、各スレッドはn個の実行のみを実行した後、CPUは他のスレッドを実行することができる.したがって、次のような問題が発生する可能性があります.
ロックは使用されていません:
ロックの使用:
event
pythonスレッドのイベントは、主スレッドが他のスレッドの実行を制御するために使用され、イベントは主に3つの方法set、wait、clearを提供します.
イベント処理のメカニズム:グローバルに「Flag」を定義し、「Flag」の値がFalseの場合、プログラムがeventを実行する.waitメソッドはブロックされ、「Flag」の値がTrueの場合event.waitメソッドではブロックされません. clear:FlagをFalse に設定 set:「Flag」をTrue に設定
Pythonプロセス
注:プロセス間のデータはそれぞれ1部持つ必要があるため、プロセスを作成するのに非常に大きなコストがかかります.
プロセスデータ共有
プロセスはそれぞれ1部のデータを持っており、デフォルトではデータを共有できません.
プロセスの作成時(非使用時)、共有データはサブプロセスに取得され、プロセスで実行が完了したら元の値に割り当てられます.
プロセスロックの例:
プロセスプール
プロセスプール内でプロセスシーケンスを維持し、使用するとプロセスプールにプロセスを取得します.プロセスプールシーケンスに使用可能なプロセスがない場合、プロセスプールに使用可能なプロセスがあるまでプログラムは待機します.
プロセスプールには、次の2つの方法があります. apply apply_async
きょうてい
スレッドとプロセスの操作はプログラムによってシステムインタフェースをトリガし、最後の実行者はシステムである.コラボレーションの操作はプログラマーです.
コパスの存在意義:マルチスレッドアプリケーションに対して、CPUはスライス方式でスレッド間の実行を切り替え、スレッドの切り替えに時間がかかる(保存状態、次回継続).コンカレントでは、1つのスレッドのみを使用し、1つのスレッドにコードブロックの実行順序を指定します.
コンシステントの適用シーン:プログラムにCPUを必要としない操作が大量に存在する場合(IO)、コンシステントに適用する.
greenlet
gevent
IO操作の自動切替に遭遇した場合:
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は指定したアルゴリズムに従ってスケジューリングし、スライスして命令を実行する.
その他の方法:
ワイヤロック
スレッド間ではランダムスケジューリングが行われているため、各スレッドは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メソッドではブロックされません.
#!/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つの方法があります.
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/'),
])