㈠ Free與python之禪
一條命令"free"顯示內存的使用信息。 默認按照M的計數單位統計。
顯示各個參數說明 :
total表示 總計物理內存的大小。
used表示 已使用多少。
free表示 可用內存多少。
Shared表示 多個進程共享的內存總額。
Buffers/cached表示 磁碟緩存的大小。
第三行(-/+ buffers/cached)解釋
used:已使用多大。
free:可用有多少。
第四行是交換分區SWAP的,也就是我們通常所說的虛擬內存。
我們按照系統應用程序來說:系統可用內存= 系統free+buffers+cached。
"free -g",按照g的計數方式來顯示內存信息。
"free -m",按照M的計數方式來顯示內存信息。
"free -k",按照K的計數方式來顯示內存信息。
"free -t",按照總和的形式顯示內存的使用信息。
"free -s 2 -c 4"。表示為周期性展示統計內存信息。本篇實例為每隔2秒統計一次,統計4次。
"free -s 5",表示周期性展示內存使用情況,意思為每隔5秒統計展示,直到我們按下ctrl +c 鍵取消統計為止。
查看版本信息,我們執行命令"free -V",進行查看
x86是一個intel 通用計算機 系列的標准編號縮寫,也標識一套通用的 計算機指令 集合,X與處理器沒有任何關系,它是一個對所有*86系統的簡單的 通配符 定義,例如:i386, 586,奔騰(pentium)。
Intel從8086開始,286、386、486、586、P1、P2、P3、P4都用的同一種CPU架構,統稱 X86 。
如果修改了當前文件,則寫入當前文件並退出(與「:x」相同)。(注意:如果當前文件有多個窗口,如果文件被修改並且窗口被關閉,那麼文件將被寫入)。:另一方面,wq總是寫文件並退出Vim。
《Python的禪宗》,蒂姆·彼得斯著
美麗勝過醜陋。
顯性比隱性好。
簡單勝於復雜。
復雜比復雜好。
平的比嵌套的好。
稀疏比稠密好。
可讀性。
特殊情況並不足以打破規則。
盡管實用性比純潔。
錯誤不應該悄無聲息地過去。
除非顯式地沉默。
面對模稜兩可,拒絕猜測的誘惑。
應該有一種——最好只有一種——顯而易見的方法。
盡管這種方式在一開始可能並不明顯,除非你是荷蘭人。
現在總比沒有好。
雖然從來沒有比現在更好過。
如果這個實現很難解釋,那就是個壞主意。
如果實現很容易解釋,這可能是個好主意。
名稱空間是一個偉大的想法——讓我們做更多的命名空間!
㈡ 程序裝載進入內存
上一講,我們看到了如何通過鏈接器,把多個文件合並成一個最終可執行文件。在運行這些可執行文件的時候,我們其實是通過一個裝載器,解析 ELF 或者 PE 格式的可執行文件。裝載器會把對應的指令和數據載入到內存裡面來,讓 CPU 去執行。
說起來只是裝載到內存裡面這一句話的事兒,實際上裝載器需要滿足兩個要求。
第一,可執行程序載入後佔用的內存空間應該是連續的 ,執行指令的時候,程序計數器是順序地一條一條指令執行下去。這也就意味著,這一條條指令需要連續地存儲在一起。
第二,我們需要同時載入很多個程序,並且不能讓程序自己規定在內存中載入的位置。 雖然編譯出來的指令里已經有了對應的各種各樣的內存地址,但是實際載入的時候,我們其實沒有辦法確保,這個程序一定載入在哪一段內存地址上。因為我們現在的計算機通常會同時運行很多個程序,可能你想要的內存地址已經被其他載入了的程序佔用了。
要滿足這兩個基本的要求,我們很容易想到一個辦法。那就是我們可以在內存裡面,找到一段連續的內存空間,然後分配給裝載的程序,然後把這段連續的內存空間地址,和整個程序指令里指定的內存地址做一個映射。
我們把指令里用到的內存地址叫作 虛擬內存地址 (Virtual Memory Address),實際在內存硬體裡面的空間地址,我們叫 物理內存地址 (Physical Memory Address)。
程序里有指令和各種內存地址,我們只需要關心虛擬內存地址就行了。對於任何一個程序來說,它看到的都是同樣的內存地址。我們維護一個虛擬內存到物理內存的映射表,這樣實際程序指令執行的時候,會通過虛擬內存地址,找到對應的物理內存地址,然後執行。因為是連續的內存地址空間,所以我們只需要維護映射關系的起始地址和對應的空間大小就可以了。
內存分段
這種找出一段連續的物理內存和虛擬內存地址進行映射的方法,我們叫分段(Segmentation)。這里的段,就是指系統分配出來的那個連續的內存空間。
分段的辦法很好,解決了程序本身不需要關心具體的物理內存地址的問題,但它也有一些不足之處,第一個就是內存碎片(Memory Fragmentation)的問題。
我們來看這樣一個例子。我現在手頭的這台電腦,有 1GB 的內存。我們先啟動一個圖形渲染程序,佔用了 512MB 的內存,接著啟動一個 Chrome 瀏覽器,佔用了 128MB 內存,再啟動一個 Python 程序,佔用了 256MB 內存。這個時候,我們關掉 Chrome,於是空閑內存還有 1024 - 512 - 256 = 256MB。按理來說,我們有足夠的空間再去裝載一個200MB 的程序。但是,這 256MB 的內存空間不是連續的,而是被分成了兩段 128MB 的內存。因此,實際情況是,我們的程序沒辦法載入進來。
當然,這個我們也有辦法解決。解決的辦法叫 內存交換 (Memory Swapping)。
我們可以把 Python 程序佔用的那 256MB 內存寫到硬碟上,然後再從硬碟上讀回來到內存裡面。不過讀回來的時候,我們不再把它載入到原來的位置,而是緊緊跟在那已經被佔用了的 512MB 內存後面。這樣,我們就有了連續的 256MB 內存空間,就可以去載入一個新的200MB 的程序。如果你自己安裝過 Linux 操作系統,你應該遇到過分配一個 swap 硬碟分區的問題。這塊分出來的磁碟空間,其實就是專門給 Linux 操作系統進行內存交換用的。
虛擬內存、分段,再加上內存交換,看起來似乎已經解決了計算機同時裝載運行很多個程序的問題。不過,你千萬不要大意,這三者的組合仍然會遇到一個性能瓶頸。硬碟的訪問速度要比內存慢很多,而每一次內存交換,我們都需要把一大段連續的內存數據寫到硬碟上。所以,如果內存交換的時候,交換的是一個很占內存空間的程序,這樣整個機器都會顯得卡頓。
內存分頁
既然問題出在內存碎片和內存交換的空間太大上,那麼解決問題的辦法就是,少出現一些內存碎片。另外,當需要進行內存交換的時候,讓需要交換寫入或者從磁碟裝載的數據更少一點,這樣就可以解決這個問題。這個辦法,在現在計算機的內存管理裡面,就叫作 內存分頁 (Paging)。
和分段這樣分配一整段連續的空間給到程序相比,分頁是把整個物理內存空間切成一段段固定尺寸的大小 。而對應的程序所需要佔用的虛擬內存空間,也會同樣切成一段段固定尺寸的大小。這樣一個連續並且尺寸固定的內存空間,我們叫頁(Page)。從虛擬內存到物理內存的映射,不再是拿整段連續的內存的物理地址,而是按照一個一個頁來的。頁的尺寸一般遠遠小於整個程序的大小。在 Linux 下,我們通常只設置成 4KB。你可以通過命令看看你手頭的 Linux 系統設置的頁的大小。
getconf PAGE_SIZE
由於內存空間都是預先劃分好的,也就沒有了不能使用的碎片,而只有被釋放出來的很多4KB 的頁。即使內存空間不夠,需要讓現有的、正在運行的其他程序,通過內存交換釋放出一些內存的頁出來,一次性寫入磁碟的也只有少數的一個頁或者幾個頁,不會花太多時間,讓整個機器被內存交換的過程給卡住。
更進一步地,分頁的方式使得我們在載入程序的時候,不再需要一次性都把程序載入到物理內存中。我們完全可以在進行虛擬內存和物理內存的頁之間的映射之後,並不真的把頁載入到物理內存里,而是只在程序運行中,需要用到對應虛擬內存頁裡面的指令和數據時,再載入到物理內存裡面去。
實際上,我們的操作系統,的確是這么做的。當要讀取特定的頁,卻發現數據並沒有載入到物理內存里的時候,就會觸發一個來自於 CPU 的 缺頁錯誤 (Page Fault)。我們的操作系統會捕捉到這個錯誤,然後將對應的頁,從存放在硬碟上的虛擬內存里讀取出來,載入到物理內存里。這種方式,使得我們可以運行那些遠大於我們實際物理內存的程序。同時,這樣一來,任何程序都不需要一次性載入完所有指令和數據,只需要載入當前需要用到就行了。
通過虛擬內存、內存交換和內存分頁這三個技術的組合,我們最終得到了一個讓程序不需要考慮實際的物理內存地址、大小和當前分配空間的解決方案。這些技術和方法,對於我們程序的編寫、編譯和鏈接過程都是透明的。這也是我們在計算機的軟硬體開發中常用的一種方法,就是 加入一個間接層 。
通過引入虛擬內存、頁映射和內存交換,我們的程序本身,就不再需要考慮對應的真實的內存地址、程序載入、內存管理等問題了。任何一個程序,都只需要把內存當成是一塊完整而連續的空間來直接使用。
總結延伸
現在回到開頭我問你的問題,我們的電腦只要 640K 內存就夠了嗎?很顯然,現在來看,比爾·蓋茨的這個判斷是不合理的,那為什麼他會這么認為呢?因為他也是一個很優秀的程序員啊!
在虛擬內存、內存交換和內存分頁這三者結合之下,你會發現,其實要運行一個程序,「必需」的內存是很少的。CPU 只需要執行當前的指令,極限情況下,內存也只需要載入一頁就好了。再大的程序,也可以分成一頁。每次,只在需要用到對應的數據和指令的時候,從硬碟上交換到內存裡面來就好了。以我們現在 4K 內存一頁的大小,640K 內存也能放下足足 160 頁呢,也無怪乎在比爾·蓋茨會說出「640K ought to be enough for anyone」這樣的話。
不過呢,硬碟的訪問速度比內存慢很多,所以我們現在的計算機,沒有個幾 G 的內存都不好意思和人打招呼。
那麼,除了程序分頁裝載這種方式之外,我們還有其他優化內存使用的方式么?下一講,我們就一起來看看「動態裝載」,學習一下讓兩個不同的應用程序,共用一個共享程序庫的辦法。
㈢ python堆和棧的區別有哪些
堆(Heap)與棧(Stack)是開發人員必須面對的兩個概念,在理解這兩個概念時,需要放到具體的場景下,因為不同場景下,堆與棧代表不同的含義。一般情況下,有兩層含義:
(1)程序內存布局場景下,堆與棧表示的是兩種內存管理方式;
(2)數據結構場景下,堆與棧表示兩種常用的數據結構。
相關推薦:《Python教程》
堆與棧實際上是操作系統對進程佔用的內存空間的兩種管理方式,主要有如下幾種區別:
(1)管理方式不同。棧由操作系統自動分配釋放,無需我們手動控制;堆的申請和釋放工作由程序員控制,容易產生內存泄漏;
(2)空間大小不同。每個進程擁有的棧的大小要遠遠小於堆的大小。理論上,程序員可申請的堆大小為虛擬內存的大小,進程棧的大小 64bits 的 Windows 默認 1MB,64bits 的 Linux 默認 10MB;
(3)生長方向不同。堆的生長方向向上,內存地址由低到高;棧的生長方向向下,內存地址由高到低。
(4)分配方式不同。堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是由操作系統完成的,比如局部變數的分配。動態分配由alloca函數進行分配,但是棧的動態分配和堆是不同的,他的動態分配是由操作系統進行釋放,無需我們手工實現。
(5)分配效率不同。棧由操作系統自動分配,會在硬體層級對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執行,這就決定了棧的效率比較高。堆則是由C/C++提供的庫函數或運算符來完成申請與管理,實現機制較為復雜,頻繁的內存申請容易產生內存碎片。顯然,堆的效率比棧要低得多。
(6)存放內容不同。棧存放的內容,函數返回地址、相關參數、局部變數和寄存器內容等。當主函數調用另外一個函數的時候,要對當前函數執行斷點進行保存,需要使用棧來實現,首先入棧的是主函數下一條語句的地址,即擴展指針寄存器的內容(EIP),然後是當前棧幀的底部地址,即擴展基址指針寄存器內容(EBP),再然後是被調函數的實參等,一般情況下是按照從右向左的順序入棧,之後是被調函數的局部變數,注意靜態變數是存放在數據段或者BSS段,是不入棧的。出棧的順序正好相反,最終棧頂指向主函數下一條語句的地址,主程序又從該地址開始執行。堆,一般情況堆頂使用一個位元組的空間來存放堆的大小,而堆中具體存放內容是由程序員來填充的。
從以上可以看到,堆和棧相比,由於大量malloc()/free()或new/delete的使用,容易造成大量的內存碎片,並且可能引發用戶態和核心態的切換,效率較低。棧相比於堆,在程序中應用較為廣泛,最常見的是函數的調用過程由棧來實現,函數返回地址、EBP、實參和局部變數都採用棧的方式存放。雖然棧有眾多的好處,但是由於和堆相比不是那麼靈活,有時候分配大量的內存空間,主要還是用堆。
無論是堆還是棧,在內存使用時都要防止非法越界,越界導致的非法內存訪問可能會摧毀程序的堆、棧數據,輕則導致程序運行處於不確定狀態,獲取不到預期結果,重則導致程序異常崩潰,這些都是我們編程時與內存打交道時應該注意的問題。
㈣ python memory運行到99%停住了
因為遇到MemoryError的問題了。
解決方法。1.回收一些暫時不用的內存。2.修改數據類型的長度。3.讀文件的時候可以逐行讀取或者分塊讀取,避免一次性把數據都讀入到內存里,導致程序崩掉。4.修改磁碟虛擬內存。
python的psutil包可以查看內存的使用情況,直接點任務管理器也可以查看電腦的內存使用佔比,還可以kill掉一些不用的進程來釋放內存。但是如果想要釋放掉python佔用的內存,比如一些使用過後續又不再需要的數據,可以導入gc包直接刪除掉數據並回收內存。
㈤ 安裝pycharm出現讓安裝jdk是怎麼回事
重新下載安裝看看
1、首先運行pycharm 2017破解版的安裝程序安裝原版軟體。
2、選擇安裝路徑。
3、選擇在桌面創建的快捷方式,一個32位,一個64位,小編是64位自然就選64位,然後下面兩個分別是關聯.py格式文件和下載安裝java運行環境jre,小編已經有了就不安裝了,如果沒有的用戶可以選擇勾選。
4、然後一直點擊next,等待安裝完畢。
5、安裝完成。
㈥ 一篇文章帶你深度解析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:嘗試android模擬器中如何把腳本傳送到模擬器,怎麼復制到模擬器的虛擬內存卡上
文章里不是說的很清楚嗎?你先要安裝android的模擬器。就是SDK那個東西。安裝後啟動它。
其中有一個adb命令 用於與模擬器進行調試用,也可以上傳文件。
你把例子代碼編輯成一個文件,再傳遞到模擬器上去。 不過模擬器試先要設置一個SD卡。另外還要安裝一個SL4A的軟體包。
㈧ 怎樣在Win7 64位旗艦版安裝Python+Eclipse開發環境
- -安裝一樣,激活工具可以一樣。- -64位不好用個屁!!!不過一樣推薦32位。\r\n\r\n32位與64位操作系統的區別科技技術的發展,計算機也處於飛速發展的階段。32位操作系統已經開始呈現無法滿足用戶的需求了,64位也開始了接班。那32位與64位操作系統到底有什麼區別呢? \r\n\r\n區別一,設計初衷不同。64位操作系統的設計初衷是:滿足機械設計和分析、三維動畫、視頻編輯和創作,以及科學計算和高性能計算應用程序等領域中需要大量內存和浮點性能的客戶需求。換句簡明的話說就是:它們是高科技人員使用本行業特殊軟體的運行平台。而32位操作系統是為普通用戶設計的。\r\n\r\n區別二,要求配置不同。64位操作系統只能安裝在64位電腦上(CPU必須是64位的)。同時需要安裝64位常用軟體以發揮64位(x64)的最佳性能。32位操作系統則可以安裝在32位(32位CPU)或64位(64位CPU)電腦上。當然,32位操作系統安裝在64位電腦上,其硬體恰似\\「大馬拉小車\\」:64位效能就會大打折扣。\r\n\r\n區別三,運算速度不同。64位CPU GPRs(General-Purpose Registers,通用寄存器)的數據寬度為64位,64位指令集可以運行64位數據指令,也就是說處理器一次可提取64位數據(只要兩個指令,一次提取8個位元組的數據),比32位(需要四個指令,一次提取4個位元組的數據)提高了一倍,理論上性能會相應提升1倍。\r\n\r\n區別四,定址能力不同。64位處理器的優勢還體現在系統對內存的控制上。由於地址使用的是特殊的整數,因此一個ALU(算術邏輯運算器)和寄存器可以處理更大的整數,也就是更大的地址。比如,Windows Vista x64 Edition支持多達128 GB的內存和多達16 TB的虛擬內存,而32位CPU和操作系統最大隻可支持4G內存。\r\n\r\n區別五,軟體普及不同。目前,64位常用軟體比32位常用軟體,要少得多的多。道理很簡單:使用64位操作系統的用戶相對較少。因此,軟體開發商必須考慮\\「投入產出比\\」,將有限資金投入到更多使用群體的軟體之中。這也是為什麼64位軟體價格相對昂貴的重要原因(將成本攤入較少的發售之中)。
㈨ 頁面文件太小,無法完成操作
虛擬內存不夠造成的
1、滑鼠右鍵點擊計算機,然後點擊屬性。
㈩ 如何釋放Python佔用的內存
1.充分利用內存
任何一種圖像處理軟體對內存的要求都很高,Photoshop也一樣。如果你在使用Photoshop時,沒有使用其它的一些大軟體,這時你就可以將Photoshop佔用內存資源的比例提高。方法是:進行Photoshop,選擇菜單下File\Preference\Memory & Image Cache命令,將Used by Photoshop的比例提高到80%~90%即可。
2.指定虛擬內存
在處理Photoshop時,內存被用完是很正常的,到時會大大影響Photoshop處理圖像的時間,哪將怎麼解決呢?方法是:你可以用硬碟來作為內存來使用,也就是常說的虛擬內存。請選擇菜單下「File\Preference\Plug-Ins & Scratch Disks」命令。在這里的Scratch Disks下,你可以在硬碟上指定四個驅動器來作為虛擬內存,軟體默認的虛擬內存是在Windows\temp之下。當第一個虛擬內存被使用光之後,Photoshop會自動去使用第二個Scratch Dsik,這樣就提高了執行速度。
3.釋放內存與硬碟空間
在進行圖像處理時,你所進行的所有操作將會記錄在Photoshop的History(歷史記錄)工作板中。這些操作包括:復制到Clipboard(粘貼板)、Undo(恢復)、Pattern(填充物)、Histories(記錄)等幾種,選擇菜單下「Edit\Purge」命令。
進行這些操作之後,Photoshop會將這些圖像和數據保存在內存里,使用該命令後,即將這些被佔用的內存空間釋放出來(RAM:Oh! Freeden)這樣就讓Photoshop有更多的Resource(資源)可用,自然就提高了效率。但注意,如果這些操作佔用的內存比較少時,就沒有必要使用啦!
除此之外,在處理大型圖片時,Photoshop會自動產生一些臨時文件,一般都很大,如果你處理的是一個20MB大小的宣傳畫時,那麼臨時文件可能就是100~150MB。請在Windows\temp或在你設定虛擬內存的驅動器里,將產生的Photoshop臨時文件*.tmp刪除掉。