03-12 56—60


56.讀數據進程執行的代碼:def read(q):

while True:
if not q.empty():
	value = q.get(True)
	print('Get %s from queue.' % value)
	time.sleep(random.random())
else:
	break
if __name__=='__main__':
# 父進程創建Queue,並傳給各個子進程:
    q = Queue()
    pw = Process(target=write, args=(q,))
    pr = Process(target=read, args=(q,))
    # 啟動子進程pw,寫入:
    pw.start()

    # 等待pw結束:
    pw.join()

    # 啟動子進程pr,讀取:
    pr.start()
    pr.join()
    # pr進程里是死循環,無法等待其結束,只能強行終止:
    print('')
    print('所有數據都寫入並且讀完') 進程池Pool
from multiprocessing import Poolimport os, time, random
def worker(msg):
	t_start = time.time()
	print("%s開始執行,進程號為%d" % (msg,os.getpid()))
	# random.random()隨機生成0~1之間的浮點數 7.    time.sleep(random.random()*2)
	t_stop = time.time()
	print(msg,"執行完畢,耗時%0.2f" % (t_stop-t_start))
	po = Pool(3)  # 定義一個進程池,最大進程數3
	for i in range(0,10): 13.    # Pool().apply_async(要調用的目標,(傳遞給目標的參數元祖,))
	# 每次循環將會用空閑出來的子進程去調用目標    po.apply_async(worker,(i,))
	print("----start----")
	po.close()  # 關閉進程池,關閉后po不再接收新的請求 po.join()  # 等待po中所有子進程執行完成,必須放在close 語句之后 print("-----end-----")

57.multiprocessing.Pool 常用函數解析:

apply_async(func[, args[, kwds]]):使用非阻塞方式調用func(並行執行,堵塞方式必須等待上一個進程退出才能執行下一個進程),args為傳遞給func的參數列表,kwds為傳遞給func的關鍵字參數列表;
close():關閉Pool,使其不再接受新的任務;
terminate():不管任務是否完成,立即終止;
join():主進程阻塞,等待子進程的退出, 必須在close或terminate之后使用;
進程池中使用Queue
如果要使用Pool創建進程,就需要使用multiprocessing.Manager()中的 Queue(),而不是
multiprocessing.Queue(),否則會得到一條如下的錯誤信息:

RuntimeError: Queue objects should only be shared between processes through
inheritance.
from multiprocessing import Manager,Poolimport os,time,random
def reader(q):
    print("reader啟動(%s),父進程為(%s)" % (os.getpid(), os.getppid()))
    for i in range(q.qsize()):
    print("reader從Queue獲取到消息:%s" % q.get(True))
def writer(q):
    print("writer啟動(%s),父進程為(%s)" % (os.getpid(), os.getppid()))
    for i in "itcast":
    q.put(i)
if __name__=="__main__":
    print("(%s) start" % os.getpid())
    q = Manager().Queue()  # 使用Manager中的Queue
    po = Pool()
    po.apply_async(writer, (q,))
    time.sleep(1)

    # 先讓上面的任務向Queue存入數據,然后再讓下面的任務開始從中取數據 po.apply_async(reader, (q,))
    po.close()
    po.join()
    print("(%s) End" % os.getpid())

58.談談你對多進程,多線程,以及協程的理解,項目是否用?

這個問題被問的概率相當之大,其實多線程,多進程,在實際開發中用到的很少,除非是那些對項目性能要求特別高的,有的開發工作幾年了,也確實沒用過,你可以這么回答,給他扯扯什么是進程,線程(cpython中是偽多線程)的概念就行,實在不行你就說你之前寫過下載文件時,用過多線程技術,或者業余時間用過多線程寫爬蟲,提升效率。

'''
進程:一個運行的程序(代碼)就是一個進程,沒有運行的代碼叫程序,進程是系統資源分配的最
小單位,進程擁有自己獨立的內存空間,所以進程間數據不共享,開銷大。

線程:  調度執行的最小單位,也叫執行路徑,不能獨立存在,依賴進程存在一個進程至少有一個線程,叫主線程,而多個線程共享內存(數據共享,共享全局變量),從而極大地提高了程序的運行效率。

協程:是一種用戶態的輕量級線程,協程的調度完全由用戶控制。協程擁有自己的寄存器上下文和棧。

協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存
器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切
換非常快。
'''

59.解釋一下什么是鎖,有哪幾種鎖?

鎖(Lock)是 Python 提供的對線程控制的對象。有互斥鎖、遞歸鎖。

60.什么是死鎖呢?

若干子線程在系統資源競爭時,都在等待對方對某部分資源解除占用狀態,結果是誰也不願先解鎖,互相干等着,程序無法執行下去,這就是死鎖。
GIL鎖(有時候,面試官不問,你自己要主動說,增加b格,盡量別一問一答的尬聊,不然最后等到的一句話就是:你還有什么想問的么?)
GIL鎖 全局解釋器鎖(只在cpython里才有)
作用:限制多線程同時執行,保證同一時間只有一個線程執行,所以cpython里的多線程其實是偽多線程!
所以Python里常常使用協程技術來代替多線程,協程是一種更輕量級的線程,
進程和線程的切換時由系統決定,而協程由我們程序員自己決定,而模塊gevent下切換是遇到了耗時操作才會切換。
三者的關系:進程里有線程,線程里有協程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM