国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

簡述Python中的進程、線程、協程

2019-11-25 16:52:35
字體:
來源:轉載
供稿:網友

進程、線程和協程之間的關系和區別也困擾我一陣子了,最近有一些心得,寫一下。

進程擁有自己獨立的堆和棧,既不共享堆,亦不共享棧,進程由操作系統調度。

線程擁有自己獨立的棧和共享的堆,共享堆,不共享棧,線程亦由操作系統調度(標準線程是的)。

協程和線程一樣共享堆,不共享棧,協程由程序員在協程的代碼里顯示調度。

進程和其他兩個的區別還是很明顯的。

協程和線程的區別是:協程避免了無意義的調度,由此可以提高性能,但也因此,程序員必須自己承擔調度的責任,同時,協程也失去了標準線程使用多CPU的能力。

Python線程

定義:Threading用于提供線程相關的操作,線程是應用程序中工作的最小單元。

#!/usr/bin/env python# -*- coding:utf-8 -*-import threadingimport timedef 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 逐個執行每個線程,執行完畢后繼續往下執行,該方法使得多線程變得無意義

•run 線程被cpu調度后自動執行線程對象的run方法

線程鎖

由于線程之間是進行隨機調度,并且每個線程可能只執行n條執行之后,CPU接著執行其他線程。所以,可能出現如下問題:

import threadingimport timegl_num = 0def show(arg):global gl_numtime.sleep(1)gl_num +=1print gl_numfor i in range(10):t = threading.Thread(target=show, args=(i,))t.start()print 'main thread stop' import threadingimport timegl_num = 0lock = threading.RLock()def Func():lock.acquire()global gl_numgl_num +=1time.sleep(1)print gl_numlock.release()for i in range(10):t = threading.Thread(target=Func)t.start() 

event

python線程的事件用于主線程控制其他線程的執行,事件主要提供了三個方法 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 threadingdef 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 進程

from multiprocessing import Processimport threadingimport timedef foo(i):print 'say hi',ifor i in range(10):p = Process(target=foo,args=(i,))p.start() 

注意:由于進程之間的數據需要各自持有一份,所以創建進程需要的非常大的開銷。

進程數據共享

進程各自持有一份數據,默認無法共享數據

#!/usr/bin/env python#coding:utf-8from multiprocessing import Processfrom multiprocessing import Managerimport timeli = []def foo(i):li.append(i)print 'say hi',lifor i in range(10):p = Process(target=foo,args=(i,))p.start()print ('ending',li) 

#方法一,Array

from multiprocessing import Process,Arraytemp = Array('i', [11,22,33,44])def Foo(i):temp[i] = 100+ifor item in temp:print i,'----->',itemfor i in range(2):p = Process(target=Foo,args=(i,))p.start()

#方法二:manage.dict()共享數據

from multiprocessing import Process,Managermanage = Manager()dic = manage.dict()def Foo(i):dic[i] = 100+iprint dic.values()for i in range(2):p = Process(target=Foo,args=(i,))p.start()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, RLockdef Foo(lock,temp,i):"""將第0個數加100"""lock.acquire()temp[0] = 100+ifor item in temp:print i,'----->',itemlock.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() 

進程池

進程池內部維護一個進程序列,當使用時,則去進程池中獲取一個進程,如果進程池序列中沒有可供使用的進進程,那么程序就會等待,直到進程池中有可用進程為止。

進程池中有兩個方法:

•apply

•apply_async

#!/usr/bin/env python# -*- coding:utf-8 -*-from multiprocessing import Process,Poolimport timedef Foo(i):time.sleep(2)return i+100def Bar(arg):print argpool = Pool(5)#print pool.apply(Foo,(1,))#print pool.apply_async(func =Foo, args=(1,)).get()for i in range(10):pool.apply_async(func=Foo, args=(i,),callback=Bar)print 'end'pool.close()

pool.join()#進程池中進程執行完畢后再關閉,如果注釋,那么程序直接關閉

協程

線程和進程的操作是由程序觸發系統接口,最后的執行者是系統;協程的操作則是程序員。

協程存在的意義:對于多線程應用,CPU通過切片的方式來切換線程間的執行,線程切換時需要耗時(保存狀態,下次繼續)。協程,則只使用一個線程,在一個線程中規定某個代碼塊執行順序。

協程的適用場景:當程序中存在大量不需要CPU的操作時(IO),適用于協程;

greenlet

#!/usr/bin/env python# -*- coding:utf-8 -*-from greenlet import greenletdef test1():print 12gr2.switch()print 34gr2.switch()def test2():print 56gr1.switch()print 78gr1 = greenlet(test1)gr2 = greenlet(test2)gr1.switch() 

gevent

import geventdef 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 geventimport urllib2def 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/'),]) 

以上所述是小編給大家介紹的Python中的進程、線程、協程的相關知識,希望對大家有所幫助!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 滨州市| 杨浦区| 宿松县| 封开县| 龙口市| 抚顺县| 昭觉县| 鄂州市| 堆龙德庆县| 长宁区| 徐闻县| 石棉县| 正宁县| 台东市| 苗栗市| 万山特区| 额敏县| 库尔勒市| 丹棱县| 东兴市| 即墨市| 中西区| 老河口市| 惠安县| 策勒县| 宁都县| 墨脱县| 扎鲁特旗| 马山县| 皮山县| 上思县| 六安市| 长宁县| 万安县| 泽州县| 定日县| 云和县| 武威市| 临海市| 揭西县| 开平市|