Python 程序與執行緒理論基礎 Day10

2022-08-09 06:54:11 字數 4052 閱讀 3180

理論基礎:

一 作業系統的作用:

1:隱藏醜陋複雜的硬體介面,提供良好的抽象介面

2:管理、排程程序,並且將多個程序對硬體的競爭變得有序

二 多道技術:

1.產生背景:針對單核,實現併發(現在的主機一般是多核,那麼每個核都會利用多道技術,但是核與核之間沒有使用多道技術切換這麼一說,乙個程式io阻塞,會等到io結束再重新排程)

2.時間上的復用(復用乙個cpu的時間片)+空間上的復用(如記憶體中同時有多道程式)

程序:正在進行的乙個過程或者說乙個任務。而負責執行任務則是cpu。
程式僅僅只是一堆**而已,而程序指的是程式的執行過程。
無論是並行還是併發,在使用者看來都是'同時'執行的,不管是程序還是執行緒,都只是乙個任務而已,真是幹活的是cpu,cpu來做這些任務,而乙個cpu同一時刻只能執行乙個任務

一 併發:是偽並行,即看起來是同時執行。單個cpu+多道技術就可以實現併發,(並行也屬於併發)

二 並行:同時執行,只有具備多個cpu才能實現並行

單核下,可以利用多道技術,多個核,每個核也都可以利用多道技術(多道技術是針對單核而言的)

有四個核,六個任務,這樣同一時間有四個任務被執行,假設分別被分配給了cpu1,cpu2,cpu3,cpu4,

一旦任務1遇到i/o就被迫中斷執行,此時任務5就拿到cpu1的時間片去執行,這就是單核下的多道技術

而一旦任務1的i/o結束了,作業系統會重新呼叫它(需知程序的排程、分配給哪個cpu執行,由作業系統說了算),可能被分配給四個cpu中的任意乙個去執行

同步執行:乙個程序在執行某個任務時,另外乙個程序必須等待其執行完畢,才能繼續執行

非同步執行:乙個程序在執行某個任務時,另外乙個程序無需等待其執行完畢,就可以繼續執行,當有訊息返回時,系統會通知後者進行處理,這樣可以提高執行效率

舉個例子,打**時就是同步通訊,發短息時就是非同步通訊。
但凡是硬體,都需要有作業系統去管理,只要有作業系統,就有程序的概念,就需要有建立程序的方式,一些作業系統只為乙個應用程式設計,比如微波爐中的控制器,一旦啟動微波爐,所有的程序都已經存在。

而對於通用系統(跑很多應用程式),需要有系統執行過程中建立或撤銷程序的能力,主要分為4中形式建立新的程序

1. 系統初始化(檢視程序linux中用ps命令,windows中用任務管理器,前台程序負責與使用者互動,後台執行的程序與使用者無關,執行在後台並且只在需要時才喚醒的程序,稱為守護程序,如電子郵件、web頁面、新聞、列印)

2. 乙個程序在執行過程中開啟了子程序(如nginx開啟多程序,os.fork,subprocess.popen等)

3. 使用者的互動式請求,而建立乙個新程序(如使用者雙擊暴風影音)

4. 乙個批處理作業的初始化(只在大型機的批處理系統中應用)

無論哪一種,新程序的建立都是由乙個已經存在的程序執行了乙個用於建立程序的系統呼叫而建立的:

1. 在unix中該系統呼叫是:fork,fork會建立乙個與父程序一模一樣的副本,二者有相同的儲存映像、同樣的環境字串和同樣的開啟檔案(在shell直譯器程序中,執行乙個命令就會建立乙個子程序)

2. 在windows中該系統呼叫是:createprocess,createprocess既處理程序的建立,也負責把正確的程式裝入新程序。

關於建立的子程序,unix和windows

1. 正常退出(自願,如使用者點選互動式頁面的叉號,或程式執行完畢呼叫發起系統呼叫正常退出,在linux中用exit,在windows中用exitprocess)

2. 出錯退出(自願,python a.py中a.py不存在)

3. 嚴重錯誤(非自願,執行非法指令,如引用不存在的記憶體,1/0等,可以捕捉異常,try...except...)

4. 被其他程序殺死(非自願,如kill -9)

無論unix還是windows,程序只有乙個父程序,不同的是:

1. 在unix中所有的程序,都是以init程序為根,組成樹形結構。父子程序共同組成乙個程序組,這樣,當從鍵盤發出乙個訊號時,該訊號被送給當前與鍵盤相關的程序組中的所有成員。

2. 在windows中,沒有程序層次的概念,所有的程序都是地位相同的,唯一類似於程序層次的暗示,是在建立程序時,父程序得到乙個特別的令牌(稱為控制代碼),該控制代碼可以用來控制子程序,但是父程序有權把該控制代碼傳給其他子程序,這樣就沒有層次了。

回到頂部

tail -f access.log |grep '404'

執行程式tail,開啟乙個子程序,執行程式grep,開啟另外乙個子程序,兩個程序之間基於管道'|'通訊,將tail的結果作為grep的輸入。

程序grep在等待輸入(即i/o)時的狀態稱為阻塞,此時grep命令都無法執行

其實在兩種情況下會導致乙個程序在邏輯上不能執行,

1. 程序掛起是自身原因,遇到i/o阻塞,便要讓出cpu讓其他程序去執行,這樣保證cpu一直在工作

2. 與程序無關,是作業系統層面,可能會因為乙個程序占用時間過多,或者優先順序等原因,而呼叫其他的程序去使用cpu。

因而乙個程序由三種狀態

程序併發的實現在於,硬體中斷乙個正在執行的程序,把此時程序執行的所有狀態儲存下來,為此,作業系統維護一張**,即程序表(process table),每個程序占用乙個程序表項(這些表項也稱為程序控制塊)

該錶存放了程序狀態的重要資訊:程式計數器、堆疊指標、記憶體分配狀況、所有開啟檔案的狀態、帳號和排程資訊,以及其他在程序由執行態轉為就緒態或阻塞態時,必須儲存的資訊,從而保證該程序在再次啟動時,就像從未被中斷過一樣。

在傳統作業系統中,每個程序有乙個位址空間,而且預設就有乙個控制線程

執行緒顧名思義,就是一條流水線工作的過程,一條流水線必須屬於乙個車間,乙個車間的工作過程是乙個程序

車間負責把資源整合到一起,是乙個資源單位,而乙個車間內至少有乙個流水線

流水線的工作需要電源,電源就相當於cpu

所以,程序只是用來把資源集中到一起(程序只是乙個資源單位,或者說資源集合),而執行緒才是cpu上的執行單位。

多執行緒(即多個控制線程)的概念是,在乙個程序中存在多個控制線程,多個控制線程共享該程序的位址空間,相當於乙個車間內有多條流水線,都共用乙個車間的資源。

例如,北京地鐵與上海地鐵是不同的程序,而北京地鐵裡的13號線是乙個執行緒,北京地鐵所有的線路共享北京地鐵所有的資源,比如所有的乘客可以被所有線路拉。
建立程序的開銷要遠大於執行緒?

如果我們的軟體是乙個工廠,該工廠有多條流水線,流水線工作需要電源,電源只有乙個即cpu(單核cpu)

乙個車間就是乙個程序,乙個車間至少一條流水線(乙個程序至少乙個執行緒)

建立乙個程序,就是建立乙個車間(申請空間,在該空間內建至少一條流水線)

而建執行緒,就只是在乙個車間內造一條流水線,無需申請空間,所以建立開銷小

程序之間是競爭關係,執行緒之間是協作關係?

車間直接是競爭/搶電源的關係,競爭(不同的程序直接是競爭關係,是不同的程式設計師寫的程式執行的,迅雷搶占其他程序的網速,360把其他程序當做病毒乾死)

乙個車間的不同流水線式協同工作的關係(同乙個程序的執行緒之間是合作關係,是同乙個程式寫的程式內開啟動,迅雷內的執行緒是合作關係,不會自己幹自己)

1. 多執行緒共享乙個程序的位址空間

2. 執行緒比程序更輕量級,執行緒比程序更容易建立可撤銷,在許多作業系統中,建立乙個執行緒比建立乙個程序要快10-100倍,在有大量執行緒需要動態和快速修改時,這一特性很有用

3. 若多個執行緒都是cpu密集型的,那麼並不能獲得效能上的增強,但是如果存在大量的計算和大量的i/o處理,擁有多個執行緒允許這些活動彼此重疊執行,從而會加快程式執行的速度。

4. 在多cpu系統中,為了最大限度的利用多核,可以開啟多個執行緒(比開程序開銷要小的多)

開啟乙個字處理軟體程序,該程序肯定需要辦不止一件事情,比如監聽鍵盤輸入,處理文字,定時自動將文字儲存到硬碟,這三個任務操作的都是同一塊資料,因而不能用多程序。只能在乙個程序裡併發地開啟三個執行緒,如果是單執行緒,那就只能是,鍵盤輸入時,不能處理文字和自動儲存,自動儲存時又不能輸入和處理文字。

程序的理論基礎

作業系統介於計算機硬體和軟體之間,本質也是乙個軟體,用來協調,管理和控制計算機和軟體的控制大軟體,由作業系統的核心以及系統呼叫兩部分組成,所處的位置如下 作用 隱藏醜陋複雜的硬體介面,提供良好的抽象介面 管理,排程程序,將多個程序變得有序 多道技術 產生背景 針對單核,實現併發 空間上的復用 記憶體...

Python之網路程式設計程序理論基礎

背景知識 顧名思義,程序即乙個軟體正在進行的過程。程序是對正在執行程式的乙個抽象。程序的概念起源於作業系統,是作業系統最核心的概念,也是作業系統提供的最古老的也是最重要的抽象概念之一。作業系統的其他所有內容都是圍繞程序的概念展開的。所以想要真正了解程序,必須先了解作業系統。詳見部落格點選進入。須知的...

Python爬蟲 理論基礎

其實爬蟲沒有大家想象的那麼複雜,有時候也就是幾行 的事兒,千萬不要把自己嚇倒了。這篇就清晰地講解一下利用python爬蟲的理論基礎。首先說明爬蟲分為三個步驟,也就需要用到三個工具。利用網頁解析器解析需要的url,進而進行匹配。url管理器有三大類。記憶體 以set形式儲存在記憶體中 儲存在關係型資料...