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

首頁 > 編程 > Python > 正文

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

2020-01-04 17:36:14
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Python中的進程、線程、協程的相關資料,需要的朋友可以參考下
 

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

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

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

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

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

協程和線程的區別是:協程避免了無意義的調度,由此可以提高性能,但也因此,程序員必須自己承擔調度的責任,同時,協程也失去了標準線程使用多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://m.vevb.com/'),]) 

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 奇台县| 藁城市| 出国| 龙游县| 龙南县| 德化县| 宣化县| 都匀市| 辽源市| 舞钢市| 武强县| 永安市| 团风县| 巍山| 黑山县| 上思县| 久治县| 城固县| 青海省| 横峰县| 巴林右旗| 巴林左旗| 西乡县| 潮安县| 九寨沟县| 阜南县| 镇巴县| 乌兰察布市| 南溪县| 金寨县| 衡山县| 轮台县| 永定县| 拉萨市| 凤山市| 奉化市| 收藏| 新兴县| 四平市| 蓝田县| 沂源县|