Day10 PythonWeb全棧課程課堂內容
Day10 PythonWeb全棧課程課堂內容
1. 程式和程式
- 區別:沒有執行的程式碼叫做程式,如pycharm.exe,而當程式碼執行起來以後就是程式。
- 一個程式可以對應多個程式。
程式的排程
- 先來先服務排程演算法:對長作業有利,對短作業無益。
- 短作業優先排程演算法。
- 時間片輪轉 + 多級反饋列隊。
程式狀態介紹
# 進入就緒狀態
import time
# 程式開始執行
print("start")
# 阻塞狀態
name = input("input:")
# 使用者輸入,解除阻塞狀態。
# 就緒
# 程式開始執行
print(name)
# 阻塞
time.sleep(1)
# 就緒
print('end')
# 結束
同步和非同步
- 同步:任務提交之後,原地等待任務的返回結果,等待的過程中不做任何事情。
- 非同步:任務提交之後,不原地等待任務的返回結果,直接做其他的事情。
阻塞和非阻塞
- 阻塞:程式停滯,不會繼續往下走。
- 非阻塞:程式不停滯,繼續往下走。 就緒態、執行態。
2. python 實現多程式
通過 multiprocessing.Process模組
- group:引數未使用,預設值為None。
- target:表示呼叫物件,即子程式要執行的任務。
- args:表示呼叫的位置引數元祖。
- kwargs:表示呼叫物件的字典。
- name:子程式名稱
import multiprocessing
import time
def task1():
while True:
print('--1--')
time.sleep(1)
def task2():
while True:
print('--1--')
time.sleep(2)
def main():
p1 = multiprocessing.Process(target=task1)
p2 = multiprocessing.Process(target=task2)
p1.start()
p2.start()
if __name__ == '__main__':
main()
注意:多個程式同時執行的順序是隨機的。
通過繼承Process類建立程式
import multiprocessing
import time
class MyProcess(multiprocessing.Process):
def run(self):
print('---')
time.sleep(1)
c = MyProcess()
c.run()
程式與執行緒區別
-
根本區別
程式:作業系統資源分配的基本單位
執行緒:任務排程和執行的基本單位
-
開銷
程式:通過複製程式碼+資源建立子程式 每個程式都有獨立的程式碼和資料空間,程式之間的切換會有較大的開銷
執行緒:在同一份程式碼裡 建立執行緒 共享記憶體 開銷較小
-
分配記憶體
程式:系統在執行的時候為每個程式分配不同的記憶體空間
執行緒:執行緒所使用的資源是它所屬的程式的資源
-
包含關係
程式:一個程式可以擁有多個執行緒
執行緒:執行緒是程式的一部分
3. 程式join方法
from multiprocessing import Process
import time
def task(n):
print("hello", n)
time.sleep(n)
print('Python', n)
if __name__ == '__main__':
p1 = Process(target=task, args=(1,))
p2 = Process(target=task, args=(2,))
p3 = Process(target=task, args=(3,))
start_time = time.time()
p1.start()
p2.start()
p3.start()
print(time.time() - start_time) # 主程式的時間
- 如果我們要等到子程式結束之後列印時間。
from multiprocessing import Process
import time
def task(n):
print("hello", n)
time.sleep(n)
print('Python', n)
if __name__ == '__main__':
p1 = Process(target=task, args=(1,))
p2 = Process(target=task, args=(2,))
p3 = Process(target=task, args=(3,))
start_time = time.time()
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print(time.time() - start_time)
加上join()
之後會發現時間變為越3s,相當於本程式中等,p3.jion()
子程式結束之後計算p3子程式的時間。
同樣的將print(time.time() - start_time)
放置在p2.join()
之後你會得到約2s的時間,表示在計算p2子程式的時間。放置在p1之後也是同一個道理。
from multiprocessing import Process
import time
def task(n):
print("hello", n)
time.sleep(n)
print('Python', n)
if __name__ == '__main__':
start_time = time.time()
for i in range(1, 4):
p = Process(target=task, args=(i, ))
p.start()
p.join()
print(time.time() - start_time)
為什麼時間邊長?:因為前面的程式是p1.start()
,p2.start()
,p3.start()
是同時執行的,而現在迴圈內部先p1.start()
結束之後,再p2.start()
,最後p3.start()
,所以時間就比較長了。
- 解決此問題
# 建立一個列表
from multiprocessing import Process
import time
def task(n):
print("hello", n)
time.sleep(n)
print('Python', n)
if __name__ == '__main__':
start_time = time.time()
p_list = []
for i in range(1, 4):
p = Process(target=task, args=(i, ))
p.start()
p_list.append(p)
for p in p_list:
p.join()
print(time.time() - start_time)
4. 佇列
from multiprocessing import Queue
# 建立物件 佇列
q = Queue(3)
# 存資料
q.put(3)
q.put("hello")
q.put([1,2])
# 取資料
print(q.get())
print(q.get())
print(q.get())
注意:
存資料的型別並沒有限制。
Queue
內的數值表示能儲存多少資料。當Queue(3)
時只能儲存q.put(3)
,q.put("hello")
,q.put([1,2])
當儲存資料大於建立物件的佇列,就會使得程式發生停滯。
取資料裡面當取資料的數量大於儲存資料的數量時,同樣最後程式也會發生停滯。
full()
方法,用於判斷佇列內是否為滿。
empty()
方法,用於判斷佇列內是否為空。
put_nowait()
方法,本質上和put()
一樣,只不過如果佇列滿了就會報異常。
get_nowait()
方法,本質上和get()
一樣,只不過如果佇列空了就會報異常。
- 佇列作用
程式1和程式2之間完全不限解耦,只要經過中間灰色的佇列,程式1將檔案放在佇列中,程式2從佇列中獲得。
5. 程式間全域性變數的共享
import multiprocessing
a = 100
def task():
global a
a += 100
def task1():
print(a)
if __name__ == '__main__':
p1 = multiprocessing.Process(target=task)
p2 = multiprocessing.Process(target=task1)
p1.start()
p2.start()
證明多程式之間的全域性變數是不受影響的,且為相互獨立的。
6. 佇列的簡單通訊
# @Time : 2021/1/3 2:10
# @Author : Sam
# @File : 佇列的簡單通訊.py
# @Software: PyCharm
import multiprocessing
def download(q):
'''下載資料'''
li = [1, 2, 3]
for item in li:
q.put(item)
def analysis(q):
'''資料處理'''
data = []
while True:
q_data = q.get()
data.append(q_data)
if q.empty():
break
print(data)
def main():
# 建立一個佇列
q = multiprocessing.Queue()
p1 = multiprocessing.Process(target=download, args=(q,))
p2 = multiprocessing.Process(target=analysis, args=(q,))
p1.start()
p2.start()
if __name__ == '__main__':
main()
- 模擬下載延時
import multiprocessing
import time
import random
def download(q):
'''下載資料'''
li = [1, 2, 3]
for item in li:
q.put(item)
time.sleep(random.randint(1, 3))
def analysis(q):
'''資料處理'''
data = []
while True:
q_data = q.get()
data.append(q_data)
if q.empty():
break
print(data)
def main():
# 建立一個佇列
q = multiprocessing.Queue()
p1 = multiprocessing.Process(target=download, args=(q,))
p2 = multiprocessing.Process(target=analysis, args=(q,))
p1.start()
p1.join()
p2.start()
if __name__ == '__main__':
main()
start() 與 run() 區別
- start() 方法來啟動程式,真正實現了多程式執行,這時無需等待 run 方法體程式碼執行完畢而直接繼續執行下面的程式碼:呼叫 Process 類的 start() 方法來啟動一個程式,這時此程式處於就緒(可執行)狀態,並沒有執行,一旦得到 cpu 時間片,就開始執行 run() 方法,這裡方法 run() 稱為程式體,當程式結束後,不可以重新啟動。
- run() 方法只是類的一個普通方法,如果直接呼叫 run 方法,程式中依然只有主執行緒這一個執行緒,其程式執行路徑還是隻有一條,還是要順序執行,還是要等待 run 方法體執行完畢後才可繼續執行下面的程式碼,這樣就沒有達到寫執行緒的目的。
# 特殊情況 持續執行
import multiprocessing
def download(q):
'''下載資料'''
li = [1, 2, 3]
for item in li:
q.put(item)
def analysis(q):
'''資料處理'''
data = []
while True:
print(q.qsize())
q_data = q.get()
data.append(q_data)
if q.empty():
break
print(data)
def main():
# 建立一個佇列
q = multiprocessing.Queue()
download(q)
analysis(q)
if __name__ == '__main__':
main()
-
為什麼會只出現兩個值原因是佇列中恰巧放進去值時,也恰好取出,造成了佇列中為空值,迴圈結束!
-
解決方法:將佇列變成全域性變數就可以。
import multiprocessing
def download(q):
global li
li = [1, 2, 3]
for item in li:
q.put(item)
def analysis(q):
'''資料處理'''
data = []
while True:
print(q.qsize())
q_data = q.get()
data.append(q_data)
if len(data) == len(li):
break
print(data)
def main():
# 建立一個佇列
q = multiprocessing.Queue()
download(q)
analysis(q)
if __name__ == '__main__':
main()
相關文章
- 網易雲課堂影片課件課程下載工具,如何在電腦端下載網易雲課堂影片課程課件資料到本地?
- 10.22 課程內容總結
- 計算機網路微課堂-課程概述計算機網路
- 9月10日 課程內容總結
- 【Ruby on Rails全棧課程】2.7 塊(Block)和迭代器AI全棧BloC
- 入門全棧Java程式設計師——課程介紹全棧Java程式設計師
- 享學課堂java架構師VIP課程全套完整Java架構
- 學堂線上影片課件課程下載工具,如何在電腦端下載學堂線上影片課程課件資料PDF,PPT到本地?
- 課程第九天內容《基礎交換九》補充內容操作
- Python全棧視訊教程-尹成-專題視訊課程Python全棧
- unity3d學校的課程內容有哪些?Unity3D
- 課堂練習
- 整理課程中將程式碼部署上線(Heroku)的內容
- 參加軟體測試學習課程有哪些內容?
- 課堂知識整理
- 課堂筆記4筆記
- java全棧工程師:從java後端到全棧,高階電商全棧系統大課Java全棧工程師後端
- python全棧工程師-CSDN就業班-專題視訊課程Python全棧工程師就業
- 平行計算與並行程式設計課程內容介紹並行行程程式設計
- 達內課程學習筆記筆記
- sql_彙總課堂參與資訊表到課堂評分表SQL
- linux課堂視訊Linux
- 如何搭建“網路課堂”
- hadoop課堂筆記Hadoop筆記
- 對分課堂總結
- 9.23課堂作業
- 終於等到你!全棧資料課出書了!全棧
- 復旦大學學生開發“課堂互動神器” 讓課堂變“酷”
- 開課吧Web全棧架構師正式課(Vue.JS及實戰專案)Web全棧架構Vue.js
- 抖音課堂上面買的課程快過期了怎麼辦?手把手教你如何下載抖音課堂(學浪)上已購買的影片課程!
- WebApp 安全風險與防護課堂開課了!WebAPP
- Python爬蟲入門教程 21-100 網易雲課堂課程資料抓取Python爬蟲
- Linux課程適合0基礎學嗎?要學習哪些內容?Linux
- Linux課程零基礎可以學習嗎?學習哪些內容?Linux
- Java課堂 第四周Java
- Flutter小課堂:Text知多少Flutter
- 課堂作業--黑客語解密黑客解密
- 江民小課堂之防毒引擎防毒