在前面使用Python Socket來編寫簡版SSH程式的時候,其實已經有使用多線程,不過當時對多線程的概念并不能很好的了解,在看了《程序與線程的一個簡單解釋》與學習了Python多線程之後,也算是有一個大緻的了解了。
内容主要如下:
1
2
3
<code>1</code><code>.Python中的多線程</code>
<code>2</code><code>.Python多線程使用方法</code><code>1</code>
<code>3</code><code>.Python多線程使用方法</code><code>2</code>
1.Python中的多線程
執行一個程式,即在作業系統中開啟了一個程序,在某一時刻,一個CPU核心隻能進行一個程序的任務,現在的計算機所說的多程序/多任務其實是通過加快CPU的執行速度來實作的,因為一個CPU每秒能執行上億次的計算,能夠對程序進行很多次切換,是以在人為可以感覺的時間裡,看上去,計算機确實是在同時執行多個程式,即同時處理多個程序。
一個程序中可以包含有多個線程,這多個線程為實作該程序的某個主要功能而運作着,多個線程可以進行串行工作,也可以并發同時進行工作,顯然後者可以節省更多的時間。
下面是自己在學習過程中的一些課堂筆記,因為還沒有真正學習一些理論,是以可能會有些錯誤,但目前是友善自己的了解:
4
5
6
7
8
9
<code>即GLI是以CPU核心為機關來控制全局鎖,是以是不能跨不同的CPU(核心 )的</code>
<code>GLI可以保證同一個程序中,某一個線程的共享資料在某一時刻隻能同時被另外一個線程修改(使用),</code>
<code>而不能同時被多個線程修改(使用),如果去掉GLI,則需要自己為線程加鎖,這樣之後,性能比原來還要差。</code>
<code>當然,難道就不能充分利用多核CPU或多個CPU了?</code>
<code>做成多程序就可以了,不同的程序運作在不同的CPU(核心)上,也可以實作并發,</code>
<code>隻是這樣的話就會比較浪費記憶體空間,考慮同時運作</code><code>10</code><code>個QQ程式的情況,</code>
<code>假如</code><code>1</code><code>個QQ占用500M的記憶體空間,則</code><code>10</code><code>個QQ就要占用5G的記憶體空間了。但如果是多線程的話,</code>
<code>可能</code><code>10</code><code>個QQ還是共享着這500M的記憶體空間。還有一個缺點就是,多程序間的資料直接通路可能</code>
<code>會比較麻煩,但其實也是可以實作的,比如chrome浏覽器就是用多程序實作的。</code>
目前首先要明确的是,Python中是不能把一個程序的多個線程分布在不同的CPU核心上運作的。
2.Python多線程使用方法1
給出下面的程式代碼及注釋:
10
<code>import</code> <code>threading #Python多線程子產品</code>
<code>import</code> <code>time</code>
<code>def run(num):</code>
<code> </code><code>print </code><code>'Hi, I am thread %s..lalala'</code> <code>% num</code>
<code> </code><code>time.sleep(</code><code>1</code><code>)</code>
<code>for</code> <code>i </code><code>in</code> <code>range(</code><code>20</code><code>):</code>
<code> </code><code>t = threading.Thread(target=run, args=(i,)) #多線程使用方法,target為需要執行多線程的函數,args為函數中的參數,注意這裡的參數寫成(i,),即如果隻能一個參數,也要加上一個</code><code>","</code>
<code> </code><code>t.start() #開始執行多線程</code>
程式運作結果如下:
11
12
13
14
15
16
17
18
19
20
21
<code>xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6$ python thread4.py </code>
<code>Hi, I am thread </code><code>0</code><code>..lalala</code>
<code>Hi, I am thread </code><code>1</code><code>..lalala</code>
<code>Hi, I am thread </code><code>2</code><code>..lalala</code>
<code>Hi, I am thread </code><code>3</code><code>..lalala</code>
<code>Hi, I am thread </code><code>4</code><code>..lalala</code>
<code>Hi, I am thread </code><code>5</code><code>..lalala</code>
<code>Hi, I am thread </code><code>6</code><code>..lalala</code>
<code>Hi, I am thread </code><code>7</code><code>..lalala</code>
<code>Hi, I am thread </code><code>8</code><code>..lalala</code>
<code>Hi, I am thread </code><code>9</code><code>..lalala</code>
<code>Hi, I am thread </code><code>10</code><code>..lalala</code>
<code>Hi, I am thread </code><code>11</code><code>..lalala</code>
<code>Hi, I am thread </code><code>12</code><code>..lalala</code>
<code>Hi, I am thread </code><code>13</code><code>..lalala</code>
<code>Hi, I am thread </code><code>14</code><code>..lalala</code>
<code>Hi, I am thread </code><code>15</code><code>..lalala</code>
<code>Hi, I am thread </code><code>16</code><code>..lalala</code>
<code>Hi, I am thread </code><code>17</code><code>..lalala</code>
<code>Hi, I am thread </code><code>18</code><code>..lalala</code>
<code>Hi, I am thread </code><code>19</code><code>..lalala</code>
直接看執行結果是看不出什麼的,這裡說一下這個程式的執行過程:0到19是同時列印輸入的,在列印19後,程式sleep 1秒後才結束程式的運作。
上面這個程式有20個線程執行,每個線程都是:列印字元串+sleep(1)。我們實際看到的結果是0到19同時列印,然後才sleep 1秒,但是需要注意的是,并非是20個線程才執行一次sleep(1),而是在每個線程中都執行了一次sleep(1),即該程式實際上是執行了20次sleep(1),而我們實際看到的結果是程式運作時僅僅是暫停了1秒,那是因為這20次sleep(1)是并發執行的。
上面的程式可以這麼去了解:20個線程相當于有20匹馬,20匹馬同時起跑(列印字元串),然後以同時停1秒(sleep(1)),最後同時到達終點(20個線程運作結束,即程式執行結束)。
為了更好的了解上面的程式,可以把上面的代碼改為如下:
<code>import</code> <code>threading</code>
<code> </code><code>t = threading.Thread(target=run, args=(i,))</code>
<code> </code><code>t.start()</code>
<code> </code><code>t.join() #等上一個線程執行完後再執行下一個線程</code>
執行結果如下:
執行結果看上去跟前面是一樣的,但執行過程卻是這樣的:每列印一次字元串,再暫停一秒。
通過這個程式,也就可以更好的了解Python的多線程并發執行了,當然,因為這是一個動态的過程,是以把程式執行一遍後會有更好的了解。
3.Python多線程使用方法2
程式代碼如下:
<code>import</code> <code>threading,time</code>
<code>class</code> <code>MyThread(threading.Thread):</code>
<code> </code><code>def __init__(self, num):</code>
<code> </code><code>threading.Thread.__init__(self)</code>
<code> </code><code>self.num = num</code>
<code> </code><code>def run(self): #</code><code>this</code> <code>name must be </code><code>'run'</code>
<code> </code><code>print </code><code>'I am thread %s'</code> <code>% self.num</code>
<code> </code><code>time.sleep(</code><code>2</code><code>)</code>
<code> </code><code>t = MyThread(i)</code>
程式的執行結果與方法1是一樣的,這裡就不給出了,隻是這裡利用了面向對象程式設計的思想方法來設計程式代碼。
本文轉自 xpleaf 51CTO部落格,原文連結:http://blog.51cto.com/xpleaf/1701903,如需轉載請自行聯系原作者