導航:首頁 > 編程語言 > python解釋單線程

python解釋單線程

發布時間:2025-02-20 21:17:24

❶ 在python中線程和協程的區別是什麼

在python中線程和協程的區別:1、一個線程可以擁有多個協程,這樣在python中就能使用多核CPU;2、線程是同步機制,而協程是非同步;3、 協程能保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用的狀態。

一、首先我們來了解一下線程和協程的概念

1、線程

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。線程間通信主要通過共享內存,上下文切換很快,資源開銷較少,但相比進程不夠穩定容易丟失數據。

2、協程

協程是一種用戶態的輕量級線程,協程的調度完全由用戶控制。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變數,所以上下文的切換非常快。

二、協程與線程的比較

1) 一個線程可以擁有多個協程,一個進程也可以單獨擁有多個協程,這樣python中則能使用多核CPU。

2) 線程進程都是同步機制,而協程則是非同步。

3)協程能保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用的狀態。

三、線程、協程在python中的使用

1、多線程一般是使用threading庫,完成一些IO密集型並發操作。多線程的優勢是切換快,資源消耗低,但一個線程掛掉則會影響到所有線程,所以不夠穩定。現實中使用線程池的場景會比較多,具體可參考《python線程池實現》。

2、協程一般是使用gevent庫,當然這個庫用起來比較麻煩,所以使用的並不是很多。相反,協程在tornado的運用就多得多了,使用協程讓tornado做到單線程非同步,據說還能解決C10K的問題。所以協程使用的地方最多的是在web應用上。

總結一下:

IO密集型一般使用多線程或者多進程,CPU密集型一般使用多進程,強調非阻塞非同步並發的一般都是使用協程,當然有時候也是需要多進程線程池結合的,或者是其他組合方式。

推薦課程:Python高級進階視頻教程

❷ Rust VS Python:為什麼越來越流行,取代榜一 Python

2021 年,Python 又獲得了 TIOBE 年度編程語言,排名已經是第一。而 Rust 依然在 20 名以外。但依然有人認為,Rust 甚至可能取代 Python。不過這不重要,認清兩者的優缺點,進而合適的地方使用合適的語言,這才最重要。

在這個指南中,我們將比較 Rust 和 Python 這兩門語言,同時將討論它們各自的應用場景,回顧使用 Rust vs. Python 的優缺點,並解釋 Rust 為什麼越來越受歡迎(甚至可能取代 Python)。

Rust [1] 是一門系統編程語言,專注於安全,尤其是並發安全,支持函數式和命令式以及泛型等編程範式的多範式語言。Rust 在語法上和 C++ 類似,但是設計者想要在保證性能的同時提供更好的內存安全。Rust 最初是由 Mozilla 研究院的 Graydon Hoare 設計創造,然後在 Dave Herman, Brendan Eich 以及很多其他人的貢獻下逐步完善的。Rust 的設計者們通過在研發 Servo 網站瀏覽器布局引擎過程中積累的經驗優化了 Rust 語言和 Rust 編譯器。

Rust 擁有 優秀的文檔 [2] 、友好的編譯器和有用的錯誤消息,以及頂級工具,包括集成包管理器、構建工具、支持自動完成和類型檢查的智能多編輯器、自動格式化程序等等。

Rust 發布於 2010 年。雖然和 Python 相比,Rust 是一門年輕的語言,但是它的社區正在穩步增長。事實上,Rust 已經連續五年(2016,2017,2018,2019,2020)在 Stack Overflow 開發者調查的「最受喜愛編程語言」評選項目中摘取桂冠。

乍一看,Rust 的靜態化和強類型化可能看起來有點極端。但從長遠來看,這有助於防止意外的代碼行為。

Python [3] 是一門旨在幫助開發人員更有效地工作和更有效地集成系統的編程語言。Python 提供了高效的高級數據結構,還能簡單有效地面向對象編程。Python 語法和動態類型,以及解釋型語言的本質,使它成為多數平台上寫腳本和快速開發應用的編程語言,隨著版本陵純的不斷更新和語言新功能的添加,逐漸被用於獨立的、大型項目的開發。如果速度是最重要的,可以使用較低級別的 API 調用,如 CPython [4] 。

1991 年 Guido van Rossum 推出了 Python,以其代碼的可讀性、無分號和花括弧而著稱。

除了可擴展性之外,Python 還是一門解釋型語言,這使得它比大多數編譯型語言要慢。正如您可能期望的那樣,Python 擁有一個龐大的庫生態系統和一個龐大的專業社區。

Rust 被應用於系統開發、操作系統、企業系統、微控制器應用、嵌入式系統、文件系統、瀏覽器組件、虛擬現實的模擬引擎等。

當性能很重要的時候,Rust 是一種常用的語言,因為它能很好地處理大量數據。它可以處理 CPU 密集型的操作,如執行演算法,這就是為什麼 Rust 比 Python 更適合系統開發的原因。

Rust 保證了內存的安全性,讓你可以控制線程行為和線程之間滲歷的資源分配方式。這使你能夠構建復雜的系統,也使得 Rust 比 Python 更有優勢。

總而言之,你應在以下情況下使用 Rust:

Python 可以用於許多應用領域,從 Web 開發,到數據科學和分析,到 AI 和機器學習,再到軟體開發。

Python 被廣泛用於機器學習,數據科學和 AI,因為它:

在以下情況下,你應該使用 Python:

考慮到 Rust 的迅速普及、受歡迎程度和廣泛的使用案例,它幾乎不可避免地會在不久的將來超越 Python,以下是一些原因。

Rust 超越 Python 的一個主要原因是性能。因為 Rust 是直接編譯成機器代碼的,所以在你的代碼和計算機之間沒有虛擬機或解釋器。

與 Python 相比,另一個關鍵優叢汪搜勢是 Rust 的線程和內存管理。雖然 Rust 不像 Python 那樣有垃圾回收機制,但 Rust 中的編譯器會強制檢查無效的內存引用泄漏和其他危險或不規則行為。

編譯語言通常比解釋語言要快。但是,使 Rust 處於不同水平的是,它幾乎與 C 和 C ++一樣快,而且沒有額外開銷。

讓我們看一個用 Python 編寫的 O(log n) 程序的示例,並使用迭代方法計算完成任務所需的時間:

輸出:

現在,讓我們來看一下使用迭代方法用 Rust 編寫的定時 O(log n) 程序:

輸出

在沒有使用任何優化技術的情況下,Rust 和 Python 在同一台機器上執行類似的操作分別需要 4.6 微秒和 8.6 微秒。這意味著 Python 花費的時間幾乎是 Rust 的兩倍。

Python 和大多數現代編程語言一樣,被設計成內存安全的。然而,即使沒有垃圾回收。Rust 在內存安全方面卻讓 Python 望塵莫及。

Rust 採用了一種獨特的方式來確保內存安全,其中涉及所有權系統和借用檢查器(borrow checker)。Rust 的借用檢查器確保引用和指針不會超過它們所指向的數據。

Python 和其他語言一樣,提供了錯誤檢查和日誌機制。但是在讓開發者知道哪裡出了什麼問題的時候,Rust 和 Python 之間有一些差異。

舉一個 Python 變數錯誤的典型例子:

Python 輸出

Rust 中的類似示例:

Rust 輸出

在這里,Rust 推薦了可能的變數,這些變數可能是你想輸入的。Python 只會拋出錯誤,而不會給出如何修復的建議。

再舉個例子:

此代碼引發錯誤,因為默認情況下 Rust 中的變數是不可變的。除非它具有關鍵字 mut ,否則無法更改。

錯誤:

修正錯誤:

如你所見,現在它不會引發任何錯誤。除此之外,Rust 不允許不同的數據類型相互操作,除非將它們轉換為相同的類型。

因此,維護 Rust 代碼庫通常很容易。除非指定,否則 Rust 不允許更改。Python 是允許這種性質的更改的。

與大多數編譯語言相比,Rust 因其速度快、內存安全有保證、超強的可靠性、一致性和用戶友好性而備受青睞。在編程中,我們已經到了速度開始變得毫不費力的地步。

隨著技術的發展,它變得越來越快,試圖在更短的時間內做更多的事情,而不需要那麼多的權衡。Rust 幫助實現了這一點,同時又不妨礙開發者的工作。當技術試圖推動可以實現的邊界時,它也會考慮系統的安全性和可靠性,這是 Rust 背後的主要思想。

除了速度外,Python 在並行計算方面也有局限性。

Python 使用全局解釋器鎖(GIL),它鼓勵只有一個線程同時執行,以提高單線程的性能。這是一大局限,因為它意味著你不能使用多個 CPU 核進行密集計算。

如前所述,Stack Overflow 的「 2020 開發人員調查」中有 86%的受訪者將 Rust 稱為 2020 年最喜歡的編程語言。

同樣,「 2020 HackerRank 開發人員技能報告」的受訪者將 Rust 列為他們計劃下一步學習的十大編程語言:

相比之下,2019 年的調查將 Rust 排在列表的底部,這表明 Rust 開發人員社區正在迅速增長。

這些數據表明,Rust 正在成為主流開發者社區的一部分。許多大公司都在使用 Rust,一些開發者甚至用它來構建其他編程語言使用的庫。著名的 Rust 用戶包括 Mozilla、Dropbox、Atlassian、npm 和 Cloudflare 等等。

Amazon Web Service 還對 Lambda,EC2 和 S3 中的性能敏感組件採用了 Rust。在 2019 年,AWS 宣布贊助 Rust 項目,此後為 Rust 提供了 AWS 開發工具包。

公司正越來越多地用更高效的編程語言(如 Rust)取代速度較慢的編程語言。沒有其他語言能像 Rust 一樣在簡單和速度之間做出平衡。

Rust 已經發展成為一門易於使用的編程語言,因此它的使用率有所提高。盡管 Python 在機器學習/數據科學社區中佔有堅實的地位,但 Rust 在未來很可能被用作 Python 庫更有效的後端。

Rust 具有取代 Python 的巨大潛力。目前的趨勢是,在應用程序、性能和速度方面,Rust 不僅僅是一種編程語言,它還是一種思維方式。

各位看官你們覺得呢?評論區留下你的看法!

❸ python為啥運行效率不高

原因:1、python是動態語言;2、python是解釋執行,但是不支持JIT;3、python中一切都是對象,每個對象都需要維護引用計數,增加了額外的工作。4、python GIL;5、垃圾回收。

當我們提到一門編程語言的效率時:通常有兩層意思,第一是開發效率,這是對程序員而言,完成編碼所需要的時間;另一個是運行效率,這是對計算機而言,完成計算任務所需要的時間。編碼效率和運行效率往往是魚與熊掌的關系,是很難同時兼顧的。不同的語言會有不同的側重,python語言毫無疑問更在乎編碼效率,life is short,we use python。

雖然使用python的編程人員都應該接受其運行效率低的事實,但python在越多越來的領域都有廣泛應用,比如科學計算 、web伺服器等。程序員當然也希望python能夠運算得更快,希望python可以更強大。

首先,python相比其他語言具體有多慢,這個不同場景和測試用例,結果肯定是不一樣的。這個網址給出了不同語言在各種case下的性能對比,這一頁是python3和C++的對比,下面是兩個case:

從上圖可以看出,不同的case,python比C++慢了幾倍到幾十倍。

python運算效率低,具體是什麼原因呢,下列羅列一些:

第一:python是動態語言

一個變數所指向對象的類型在運行時才確定,編譯器做不了任何預測,也就無從優化。舉一個簡單的例子:r = a + b。a和b相加,但a和b的類型在運行時才知道,對於加法操作,不同的類型有不同的處理,所以每次運行的時候都會去判斷a和b的類型,然後執行對應的操作。而在靜態語言如C++中,編譯的時候就確定了運行時的代碼。

另外一個例子是屬性查找,關於具體的查找順序在《python屬性查找》中有詳細介紹。簡而言之,訪問對象的某個屬性是一個非常復雜的過程,而且通過同一個變數訪問到的python對象還都可能不一樣(參見Lazy property的例子)。而在C語言中,訪問屬性用對象的地址加上屬性的偏移就可以了。

第二:python是解釋執行,但是不支持JIT(just in time compiler)。雖然大名鼎鼎的google曾經嘗試Unladen Swallow 這個項目,但最終也折了。

第三:python中一切都是對象,每個對象都需要維護引用計數,增加了額外的工作。

第四:python GIL,GIL是Python最為詬病的一點,因為GIL,python中的多線程並不能真正的並發。如果是在IO bound的業務場景,這個問題並不大,但是在CPU BOUND的場景,這就很致命了。所以筆者在工作中使用python多線程的情況並不多,一般都是使用多進程(pre fork),或者在加上協程。即使在單線程,GIL也會帶來很大的性能影響,因為python每執行100個opcode(默認,可以通過sys.setcheckinterval()設置)就會嘗試線程的切換,具體的源代碼在ceval.c::PyEval_EvalFrameEx。

第五:垃圾回收,這個可能是所有具有垃圾回收的編程語言的通病。python採用標記和分代的垃圾回收策略,每次垃圾回收的時候都會中斷正在執行的程序,造成所謂的頓卡。infoq上有一篇文章,提到禁用Python的GC機制後,Instagram性能提升了10%。感興趣的讀者可以去細讀。

推薦課程:Python機器學習(Mooc禮欣、嵩天教授)

❹ 一篇文章帶你深度解析Python線程和進程

使用Python中的線程模塊,能夠同時運行程序的不同部分,並簡化設計。如果你已經入門Python,並且想用線程來提升程序運行速度的話,希望這篇教程會對你有所幫助。

線程與進程

什麼是進程

進程是系統進行資源分配和調度的一個獨立單位 進程是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。每個進程都有自己的獨立內存空間,不同進程通過進程間通信來通信。由於進程比較重量,占據獨立的內存,所以上下文進程間的切換開銷(棧、寄存器、虛擬內存、文件句柄等)比較大,但相對比較穩定安全。

什麼是線程

CPU調度和分派的基本單位 線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。線程間通信主要通過共享內存,上下文切換很快,資源開銷較少,但相比進程不夠穩定容易丟失數據。

進程與線程的關系圖

線程與進程的區別:

進程

現實生活中,有很多的場景中的事情是同時進行的,比如開車的時候 手和腳共同來駕駛 汽車 ,比如唱歌跳舞也是同時進行的,再比如邊吃飯邊打電話;試想如果我們吃飯的時候有一個領導來電,我們肯定是立刻就接聽了。但是如果你吃完飯再接聽或者回電話,很可能會被開除。

注意:

多任務的概念

什麼叫 多任務 呢?簡單地說,就是操作系統可以同時運行多個任務。打個比方,你一邊在用瀏覽器上網,一邊在聽MP3,一邊在用Word趕作業,這就是多任務,至少同時有3個任務正在運行。還有很多任務悄悄地在後台同時運行著,只是桌面上沒有顯示而已。

現在,多核CPU已經非常普及了,但是,即使過去的單核CPU,也可以執行多任務。由於CPU執行代碼都是順序執行的,那麼,單核CPU是怎麼執行多任務的呢?

答案就是操作系統輪流讓各個任務交替執行,任務1執行0.01秒,切換到任務2,任務2執行0.01秒,再切換到任務3,執行0.01秒,這樣反復執行下去。表面上看,每個任務都是交替執行的,但是,由於CPU的執行速度實在是太快了,我們感覺就像所有任務都在同時執行一樣。

真正的並行執行多任務只能在多核CPU上實現,但是,由於任務數量遠遠多於CPU的核心數量,所以,操作系統也會自動把很多任務輪流調度到每個核心上執行。 其實就是CPU執行速度太快啦!以至於我們感受不到在輪流調度。

並行與並發

並行(Parallelism)

並行:指兩個或兩個以上事件(或線程)在同一時刻發生,是真正意義上的不同事件或線程在同一時刻,在不同CPU資源呢上(多核),同時執行。

特點

並發(Concurrency)

指一個物理CPU(也可以多個物理CPU) 在若幹道程序(或線程)之間多路復用,並發性是對有限物理資源強制行使多用戶共享以提高效率。

特點

multiprocess.Process模塊

process模塊是一個創建進程的模塊,藉助這個模塊,就可以完成進程的創建。

語法:Process([group [, target [, name [, args [, kwargs]]]]])

由該類實例化得到的對象,表示一個子進程中的任務(尚未啟動)。

注意:1. 必須使用關鍵字方式來指定參數;2. args指定的為傳給target函數的位置參數,是一個元祖形式,必須有逗號。

參數介紹:

group:參數未使用,默認值為None。

target:表示調用對象,即子進程要執行的任務。

args:表示調用的位置參數元祖。

kwargs:表示調用對象的字典。如kwargs = {'name':Jack, 'age':18}。

name:子進程名稱。

代碼:

除了上面這些開啟進程的方法之外,還有一種以繼承Process的方式開啟進程的方式:

通過上面的研究,我們千方百計實現了程序的非同步,讓多個任務可以同時在幾個進程中並發處理,他們之間的運行沒有順序,一旦開啟也不受我們控制。盡管並發編程讓我們能更加充分的利用IO資源,但是也給我們帶來了新的問題。

當多個進程使用同一份數據資源的時候,就會引發數據安全或順序混亂問題,我們可以考慮加鎖,我們以模擬搶票為例,來看看數據安全的重要性。

加鎖可以保證多個進程修改同一塊數據時,同一時間只能有一個任務可以進行修改,即串列的修改。加鎖犧牲了速度,但是卻保證了數據的安全。

因此我們最好找尋一種解決方案能夠兼顧:1、效率高(多個進程共享一塊內存的數據)2、幫我們處理好鎖問題。

mutiprocessing模塊為我們提供的基於消息的IPC通信機制:隊列和管道。隊列和管道都是將數據存放於內存中 隊列又是基於(管道+鎖)實現的,可以讓我們從復雜的鎖問題中解脫出來, 我們應該盡量避免使用共享數據,盡可能使用消息傳遞和隊列,避免處理復雜的同步和鎖問題,而且在進程數目增多時,往往可以獲得更好的可獲展性( 後續擴展該內容 )。

線程

Python的threading模塊

Python 供了幾個用於多線程編程的模塊,包括 thread, threading 和 Queue 等。thread 和 threading 模塊允許程序員創建和管理線程。thread 模塊 供了基本的線程和鎖的支持,而 threading 供了更高級別,功能更強的線程管理的功能。Queue 模塊允許用戶創建一個可以用於多個線程之間 共享數據的隊列數據結構。

python創建和執行線程

創建線程代碼

1. 創建方法一:

2. 創建方法二:

進程和線程都是實現多任務的一種方式,例如:在同一台計算機上能同時運行多個QQ(進程),一個QQ可以打開多個聊天窗口(線程)。資源共享:進程不能共享資源,而線程共享所在進程的地址空間和其他資源,同時,線程有自己的棧和棧指針。所以在一個進程內的所有線程共享全局變數,但多線程對全局變數的更改會導致變數值得混亂。

代碼演示:

得到的結果是:

首先需要明確的一點是GIL並不是Python的特性,它是在實現Python解析器(CPython)時所引入的一個概念。就好比C++是一套語言(語法)標准,但是可以用不同的編譯器來編譯成可執行代碼。同樣一段代碼可以通過CPython,PyPy,Psyco等不同的Python執行環境來執行(其中的JPython就沒有GIL)。

那麼CPython實現中的GIL又是什麼呢?GIL全稱Global Interpreter Lock為了避免誤導,我們還是來看一下官方給出的解釋:

主要意思為:

因此,解釋器實際上被一個全局解釋器鎖保護著,它確保任何時候都只有一個Python線程執行。在多線程環境中,Python 虛擬機按以下方式執行:

由於GIL的存在,Python的多線程不能稱之為嚴格的多線程。因為 多線程下每個線程在執行的過程中都需要先獲取GIL,保證同一時刻只有一個線程在運行。

由於GIL的存在,即使是多線程,事實上同一時刻只能保證一個線程在運行, 既然這樣多線程的運行效率不就和單線程一樣了嗎,那為什麼還要使用多線程呢?

由於以前的電腦基本都是單核CPU,多線程和單線程幾乎看不出差別,可是由於計算機的迅速發展,現在的電腦幾乎都是多核CPU了,最少也是兩個核心數的,這時差別就出來了:通過之前的案例我們已經知道,即使在多核CPU中,多線程同一時刻也只有一個線程在運行,這樣不僅不能利用多核CPU的優勢,反而由於每個線程在多個CPU上是交替執行的,導致在不同CPU上切換時造成資源的浪費,反而會更慢。即原因是一個進程只存在一把gil鎖,當在執行多個線程時,內部會爭搶gil鎖,這會造成當某一個線程沒有搶到鎖的時候會讓cpu等待,進而不能合理利用多核cpu資源。

但是在使用多線程抓取網頁內容時,遇到IO阻塞時,正在執行的線程會暫時釋放GIL鎖,這時其它線程會利用這個空隙時間,執行自己的代碼,因此多線程抓取比單線程抓取性能要好,所以我們還是要使用多線程的。

GIL對多線程Python程序的影響

程序的性能受到計算密集型(CPU)的程序限制和I/O密集型的程序限制影響,那什麼是計算密集型和I/O密集型程序呢?

計算密集型:要進行大量的數值計算,例如進行上億的數字計算、計算圓周率、對視頻進行高清解碼等等。這種計算密集型任務雖然也可以用多任務完成,但是花費的主要時間在任務切換的時間,此時CPU執行任務的效率比較低。

IO密集型:涉及到網路請求(time.sleep())、磁碟IO的任務都是IO密集型任務,這類任務的特點是CPU消耗很少,任務的大部分時間都在等待IO操作完成(因為IO的速度遠遠低於CPU和內存的速度)。對於IO密集型任務,任務越多,CPU效率越高,但也有一個限度。

當然為了避免GIL對我們程序產生影響,我們也可以使用,線程鎖。

Lock&RLock

常用的資源共享鎖機制:有Lock、RLock、Semphore、Condition等,簡單給大家分享下Lock和RLock。

Lock

特點就是執行速度慢,但是保證了數據的安全性

RLock

使用鎖代碼操作不當就會產生死鎖的情況。

什麼是死鎖

死鎖:當線程A持有獨占鎖a,並嘗試去獲取獨占鎖b的同時,線程B持有獨占鎖b,並嘗試獲取獨占鎖a的情況下,就會發生AB兩個線程由於互相持有對方需要的鎖,而發生的阻塞現象,我們稱為死鎖。即死鎖是指多個進程因競爭資源而造成的一種僵局,若無外力作用,這些進程都將無法向前推進。

所以,在系統設計、進程調度等方面注意如何不讓這四個必要條件成立,如何確定資源的合理分配演算法,避免進程永久占據系統資源。

死鎖代碼

python線程間通信

如果各個線程之間各干各的,確實不需要通信,這樣的代碼也十分的簡單。但這一般是不可能的,至少線程要和主線程進行通信,不然計算結果等內容無法取回。而實際情況中要復雜的多,多個線程間需要交換數據,才能得到正確的執行結果。

python中Queue是消息隊列,提供線程間通信機制,python3中重名為為queue,queue模塊塊下提供了幾個阻塞隊列,這些隊列主要用於實現線程通信。

在 queue 模塊下主要提供了三個類,分別代表三種隊列,它們的主要區別就在於進隊列、出隊列的不同。

簡單代碼演示

此時代碼會阻塞,因為queue中內容已滿,此時可以在第四個queue.put('蘋果')後面添加timeout,則成為 queue.put('蘋果',timeout=1)如果等待1秒鍾仍然是滿的就會拋出異常,可以捕獲異常。

同理如果隊列是空的,無法獲取到內容默認也會阻塞,如果不阻塞可以使用queue.get_nowait()。

在掌握了 Queue 阻塞隊列的特性之後,在下面程序中就可以利用 Queue 來實現線程通信了。

下面演示一個生產者和一個消費者,當然都可以多個

使用queue模塊,可在線程間進行通信,並保證了線程安全。

協程

協程,又稱微線程,纖程。英文名Coroutine。

協程是python個中另外一種實現多任務的方式,只不過比線程更小佔用更小執行單元(理解為需要的資源)。為啥說它是一個執行單元,因為它自帶CPU上下文。這樣只要在合適的時機, 我們可以把一個協程 切換到另一個協程。只要這個過程中保存或恢復 CPU上下文那麼程序還是可以運行的。

通俗的理解:在一個線程中的某個函數,可以在任何地方保存當前函數的一些臨時變數等信息,然後切換到另外一個函數中執行,注意不是通過調用函數的方式做到的,並且切換的次數以及什麼時候再切換到原來的函數都由開發者自己確定。

在實現多任務時,線程切換從系統層面遠不止保存和恢復 CPU上下文這么簡單。操作系統為了程序運行的高效性每個線程都有自己緩存Cache等等數據,操作系統還會幫你做這些數據的恢復操作。所以線程的切換非常耗性能。但是協程的切換只是單純的操作CPU的上下文,所以一秒鍾切換個上百萬次系統都抗的住。

greenlet與gevent

為了更好使用協程來完成多任務,除了使用原生的yield完成模擬協程的工作,其實python還有的greenlet模塊和gevent模塊,使實現協程變的更加簡單高效。

greenlet雖說實現了協程,但需要我們手工切換,太麻煩了,gevent是比greenlet更強大的並且能夠自動切換任務的模塊。

其原理是當一個greenlet遇到IO(指的是input output 輸入輸出,比如網路、文件操作等)操作時,比如訪問網路,就自動切換到其他的greenlet,等到IO操作完成,再在適當的時候切換回來繼續執行。

模擬耗時操作:

如果有耗時操作也可以換成,gevent中自己實現的模塊,這時候就需要打補丁了。

使用協程完成一個簡單的二手房信息的爬蟲代碼吧!

以下文章來源於Python專欄 ,作者宋宋

文章鏈接:https://mp.weixin.qq.com/s/2r3_ipU3HjdA5VnqSHjUnQ

❺ 為什麼都說爬蟲PYTHON好

python上手容易,第三方庫多(go現在第三方庫也多)。

如果不考慮採集速度,不用登陸——requests,單線程,簡單的代碼如下:

url = "http://dd.com"

html = requests.get(url)

html.encoding=('GBK') #避免編碼問題 如有報錯,另外測試

print (html.text[:1000]) #輸出1000個字元,避免ide假死。

本人沒學過java c#,不清楚他們兩個一個簡單爬蟲的代碼量,想來最起碼比python的要多。

不過說實話python的工作機會沒有 java c#的多,也就是說別想著花錢去培訓班培訓了幾個月,就能找到月入過萬的工作。

python的運行效率比其他編程語言要差,不考慮效率的情況下,可以用python寫寫小代碼,有錢的可以寫scrapy代碼,堆伺服器做分布式爬蟲。

閱讀全文

與python解釋單線程相關的資料

熱點內容
小說管理系統項目源碼 瀏覽:899
php注冊判斷 瀏覽:652
我的世界伺服器名稱和地址 瀏覽:145
將軍不聽元帥命令出關 瀏覽:136
linuxawk命令 瀏覽:986
三菱plc編程軟體gxdevelop 瀏覽:402
php從入門到精通光碟下載 瀏覽:924
不能表示演算法的是什麼 瀏覽:139
讀卡器在文件夾怎麼查看照片 瀏覽:804
程序員是屬於哪個部門管理 瀏覽:617
交換機命令be 瀏覽:332
存儲壓縮加密技術情況 瀏覽:504
知名的可編程步進電機驅動器工廠 瀏覽:184
銀行卡信息加密想取消 瀏覽:219
程序員唱可愛 瀏覽:824
除了移動花卡怎麼更改定向app 瀏覽:326
python多線程java 瀏覽:255
2021程序員筆記本r5 瀏覽:662
演算法監管的要點在於 瀏覽:895
長安s460壓縮機 瀏覽:246