程序 pid 唯一标示符
使用kill殺死程序
主線程 創造一個程序的時候,會創造一個線程,這個線程被稱為主線程
一個程序隻有一個主線程
python裡的多線程,不是真正意義上的多線程,隻是多線程的假象
全局鎖GIL 在任意的指定時間裡,有且隻有一個線程在運作——>python是線程安全的
1
2
3
4
5
<code>import</code> <code>threading</code>
<code>def</code> <code>test():</code>
<code> </code><code>print</code> <code>1</code>
<code>a</code><code>=</code><code>threading.Thread(target</code><code>=</code><code>test)</code>
<code>a.start()</code>
6
7
8
9
<code>b</code><code>=</code><code>threading.Thread(target</code><code>=</code><code>test)</code>
<code>b.start()</code>
<code>a.join()</code>
<code>b.join()</code>
10
11
12
13
<code>import</code> <code>time</code>
<code> </code><code>time.sleep(</code><code>0.001</code><code>)</code>
<code>ts</code><code>=</code><code>[]</code>
<code>for</code> <code>i </code><code>in</code> <code>xrange</code><code>(</code><code>0</code><code>,</code><code>15</code><code>):</code>
<code> </code><code>th</code><code>=</code><code>threading.Thread(target</code><code>=</code><code>test,args</code><code>=</code><code>[i])</code>
<code> </code><code>th.start()</code>
<code> </code><code>ts.append(th)</code>
<code>for</code> <code>i </code><code>in</code> <code>ts:</code>
<code> </code><code>i.join() </code><code>##等待線程結束後,繼續運作腳本</code>
<code>print</code> <code>"End"</code>
日常推薦使用多程序,而不是多線程。多線程複雜度較高,可維護性差,且隻是在使用單個CPU。
一個程式的複雜度,大部分情況下,隻和代碼行數有關。
在資料庫連接配接池的場景下,可以使用多線程
io操作作用到多線程?必須要lock,acquire,release
互斥鎖
加鎖 acquire
釋放鎖 release
加鎖一定要釋放,不釋放成死鎖
<code>mlock</code><code>=</code><code>threading.Lock()</code>
<code>num</code><code>=</code><code>0</code>
<code>def</code> <code>a():</code>
<code> </code><code>global</code> <code>num</code>
<code> </code><code>mlock.acquire()</code>
<code> </code><code>num</code><code>+</code><code>=</code><code>1</code>
<code> </code><code>mlock.release()</code>
<code> </code><code>print</code> <code>num</code>
<code>for</code> <code>i </code><code>in</code> <code>xrange</code><code>(</code><code>0</code><code>,</code><code>10</code><code>):</code>
<code> </code><code>d</code><code>=</code><code>threading.Thread(target</code><code>=</code><code>a)</code>
<code> </code><code>d.start()</code>
rlock 防止死鎖
協程
包含yield的函數,則是一個可疊代對象
利用next方法,取每一次yield
send方法
生産者,消費者行為
無需立即執行,需要時才執行
<code> </code><code>i</code><code>=</code><code>0</code>
<code> </code><code>a</code><code>=</code><code>4</code>
<code> </code><code>while</code> <code>i<a:</code>
<code> </code><code>x</code><code>=</code><code>yield</code> <code>i</code>
<code> </code><code>i</code><code>+</code><code>=</code><code>1</code>
<code>t</code><code>=</code><code>test()</code>
<code>print</code> <code>t.</code><code>next</code><code>()</code>
【擴充閱讀1】
多線程向來是一個讓程式員頭痛的一個問題,不隻是初學者容易犯錯誤,很多老鳥也難免站着中槍。一旦出現問題很難定位和解決,除了可能因為程式設計者知識上的缺陷導緻的疏漏外,另一個難題就是問題重制難度大,避免多線程導緻BUG最好的方法就是預防。
首先,在開始進行多線程程式設計之前要考慮好,我們是否真的需要多線程,什麼時候才需要多線程。正所謂”大道至簡“,越簡單的設計越是好的設計,如果單個線程就可以完成任務解決問題,就不要用多個線程,不要為了炫耀一下自己的多線程程式設計能力動不動就起個線程,到最好搞不好會搬石頭砸自己的腳。那什麼情況下才需要用多線程呢,如果滿足以下兩個條件之一就不得使用多線程:
(1)單線程不能滿足業務需要。例如12306的火車票售票系統,在同一時間内可能會有NNN個請求,這些請求之間是完全獨立的,其發起時間也是沒有互相依賴關系的,背景必須使用多線程處理以保證對使用者響應的及時。
(2)單線程不能滿足性能要求且資料IO吞吐率低于CPU的處理能力。如果單個線程可以滿足性能要求根據無須考慮多線程了,在對于通路IO較多的應用中,IO(無論是讀寫資料還是等待使用者響應)會阻塞線程的運作,而CPU更多的時間處于等待外部響應的狀态,此時增加線程可以提高CPU的使用率,當有線程在等待IO的時候有别的線程在使用CPU,進而通過提高CPU的使用率而提高應用的整體性能。
其次,當确定了肯定要用多線程之後,緊接着就得考慮一個問題:用幾個線程比較合适?主要可以從以下方面考慮:
(1)業務邏輯。根據實際的業務不同要通過經驗資料來确定線程的數量,很難有統一的公式計算出來,要通過不斷的調整、測試、比較來确定一個比較合理的數字,而且随着業務的變更,參數還要重新調整。
(2)CPU數量。如果隻有一個CPU,在同一時間不可能執行兩個線程的,它們是通過時間片的輪換來實作多線程的,而線上程間的不斷切換時作業系統會有進行很多的操作,相當消費CPU資源,線程越多無謂的CPU消費也就越多。對于一個計算密集型的任務可能隻用一個線程才是效率最高的,例如對大塊記憶體資料的排序操作,沒有任何IO會阻塞線程,使用多個線程隻會無謂地消費CPU資源,隻需要一個線程一直進行排序操作即可。要想發揮CPU的最佳性能,無論對任何類型的應用,線程的最小數量就是CPU的數量,如果此時CPU還有空閑再考慮增加線程的數量,不斷調整以取得最佳的性能。
(3)記憶體大小。因為每個線程都要配置設定獨立的棧以及獨立的上下文環境,是以建立一個新的線程之後即使什麼也不幹也會消耗一定的記憶體,故而并不是線程越多性能越好。因為如果建立的線程過多記憶體不夠用,很可能導緻程式在運作過程中有虛拟記憶體的使用,将記憶體的通路轉化為低速存儲的通路,反而會負面影響應用的性能。
然而,這些因素隻是影響确定線程數的重要因素,但并沒有公式可使用,需要根據經驗對這些因素進行評估并通過試驗來确定最佳的線程數。
【擴充閱讀2】
在Thread和Process中,應當優選Process,因為Process更穩定,而且,Process可以分布到多台機器上,而Thread最多隻能分布到同一台機器的多個CPU上。
本文轉自Grodd51CTO部落格,原文連結:http://blog.51cto.com/juispan/1970411,如需轉載請自行聯系原作者