Lock元件
當我們用多程序來讀寫檔案的時候,如果一個程序是寫檔案,一個程序是讀檔案,
如果兩個檔案同時進行,肯定是不行的,必須是檔案寫結束後,才可以進行讀操作。
或者是多個程序在共享一些資源的時候,同時隻能有一個程序進行通路,那就需要鎖機制進行控制。
需求:
一個程序寫入一個檔案,一個程序追加檔案,一個程序讀檔案,同時啟動起來
我們可以通過程序的join()方法來實作,這是一種方法,本節用Lock(程序鎖)來實作。
函數說明:
# lock = multiprocessing.Lock()
# lock.acquire() #獲得鎖
# lock.release() #釋放鎖
先寫不加鎖的程式:
#不加鎖
# number +1
# number +3
<code>import</code> <code>multiprocessing</code>
<code>import</code> <code>time</code>
<code>def</code> <code>add(number,value,lock):</code>
<code> </code><code>print</code> <code>(</code><code>"init add{0} number = {1}"</code><code>.</code><code>format</code><code>(value, number))</code>
<code> </code><code>for</code> <code>i </code><code>in</code> <code>xrange</code><code>(</code><code>1</code><code>, </code><code>6</code><code>):</code>
<code> </code><code>number </code><code>+</code><code>=</code> <code>value</code>
<code> </code><code>time.sleep(</code><code>1</code><code>)</code>
<code> </code><code>print</code> <code>(</code><code>"add{0} number = {1}"</code><code>.</code><code>format</code><code>(value, number))</code>
<code> </code>
<code>if</code> <code>__name__ </code><code>=</code><code>=</code> <code>"__main__"</code><code>:</code>
<code> </code><code>lock </code><code>=</code> <code>multiprocessing.Lock()</code>
<code> </code><code>number </code><code>=</code> <code>0</code>
<code> </code><code>p1 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>add,args</code><code>=</code><code>(number, </code><code>1</code><code>, lock))</code>
<code> </code><code>p2 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>add,args</code><code>=</code><code>(number, </code><code>3</code><code>, lock))</code>
<code> </code><code>p1.start()</code>
<code> </code><code>p2.start()</code>
<code> </code><code>print</code> <code>(</code><code>"main end"</code><code>)</code>
結果:
<code>main end</code>
<code>init add1 number = 0</code>
<code>init add3 number = 0</code>
<code>add1 number = 1</code>
<code>add3 number = 3</code>
<code>add1 number = 2</code>
<code>add3 number = 6</code>
<code>add1 number = 3</code>
<code>add3 number = 9</code>
<code>add1 number = 4</code>
<code>add3 number = 12</code>
<code>add1 number = 5</code>
<code>add3 number = 15</code>
再寫加鎖的程式:
<code> </code><code>with lock:</code>
<code>init add1 number = 0 </code><code>#add1優先搶到鎖,優先執行</code>
<code>init add3 number = 0 </code><code>#add3被阻塞,等待add1執行完成,釋放鎖後執行add3</code>
使用 lock.acquire() 和 lock.release()
<code> </code><code>lock.acquire()</code>
<code> </code><code>try</code><code>:</code>
<code> </code><code>print</code> <code>(</code><code>"init add{0} number = {1}"</code><code>.</code><code>format</code><code>(value, number))</code>
<code> </code><code>for</code> <code>i </code><code>in</code> <code>xrange</code><code>(</code><code>1</code><code>, </code><code>6</code><code>):</code>
<code> </code><code>number </code><code>+</code><code>=</code> <code>value</code>
<code> </code><code>time.sleep(</code><code>1</code><code>)</code>
<code> </code><code>print</code> <code>(</code><code>"add{0} number = {1}"</code><code>.</code><code>format</code><code>(value, number))</code>
<code> </code><code>except</code> <code>Exception as e:</code>
<code> </code><code>raise</code> <code>e</code>
<code> </code><code>finally</code><code>:</code>
<code> </code><code>lock.release()</code>
<code>init add1 number </code><code>=</code> <code>0</code>
<code>add1 number </code><code>=</code> <code>1</code>
<code>add1 number </code><code>=</code> <code>2</code>
<code>add1 number </code><code>=</code> <code>3</code>
<code>add1 number </code><code>=</code> <code>4</code>
<code>add1 number </code><code>=</code> <code>5</code>
<code>init add3 number </code><code>=</code> <code>0</code>
<code>add3 number </code><code>=</code> <code>3</code>
<code>add3 number </code><code>=</code> <code>6</code>
<code>add3 number </code><code>=</code> <code>9</code>
<code>add3 number </code><code>=</code> <code>12</code>
<code>add3 number </code><code>=</code> <code>15</code>
共享記憶體
python的multiprocessing子產品也給我們提供了共享記憶體的操作
一般的變量在程序之間是沒法進行通訊的,multiprocessing 給我們提供了 Value 和 Array 子產品,他們可以在不通的程序中共同使用
例子:不加鎖,讓number加完1後再繼續加3,再繼續加一,再繼續加3...
<code>def</code> <code>add(number,add_value):</code>
<code> </code><code>print</code> <code>(</code><code>"init add{0} number = {1}"</code><code>.</code><code>format</code><code>(add_value, number.value))</code>
<code> </code><code>number.value </code><code>+</code><code>=</code> <code>add_value</code>
<code> </code><code>print</code> <code>(</code><code>"***************add{0} has added***********"</code><code>.</code><code>format</code><code>(add_value))</code>
<code> </code><code>print</code> <code>(</code><code>"add{0} number = {1}"</code><code>.</code><code>format</code><code>(add_value, number.value))</code>
<code> </code><code>number </code><code>=</code> <code>multiprocessing.Value(</code><code>'i'</code><code>, </code><code>0</code><code>)</code>
<code> </code><code>p1 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>add,args</code><code>=</code><code>(number, </code><code>1</code><code>))</code>
<code> </code><code>p2 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>add,args</code><code>=</code><code>(number, </code><code>3</code><code>))</code>
列印結果:
<code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>add1 has added</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code>
<code>init add3 number </code><code>=</code> <code>1</code>
<code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>add3 has added</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code><code>*</code>
<code>add3 number </code><code>=</code> <code>5</code>
<code>add1 number </code><code>=</code> <code>8</code>
<code>add1 number </code><code>=</code> <code>12</code>
<code>add3 number </code><code>=</code> <code>13</code>
<code>add1 number </code><code>=</code> <code>16</code>
<code>add3 number </code><code>=</code> <code>17</code>
<code>add1 number </code><code>=</code> <code>20</code>
<code>add3 number </code><code>=</code> <code>20</code>
再給加上鎖:
加1的程序加完後,再執行加上3的程序
<code>def</code> <code>add(number,add_value,lock):</code>
執行結果(對比上面):
<code>***************add1 has added***********</code>
<code>init add3 number = 5</code>
<code>***************add3 has added***********</code>
<code>add3 number = 8</code>
<code>add3 number = 11</code>
<code>add3 number = 14</code>
<code>add3 number = 17</code>
<code>add3 number = 20</code>
多程序共享記憶體實作:
<code> </code><code>except</code> <code>Exception as e:</code>
<code> </code><code>raise</code> <code>e</code>
<code> </code><code>finally</code><code>:</code>
<code> </code><code>lock.release()</code>
<code>def</code> <code>change(arr):</code>
<code> </code><code>for</code> <code>i </code><code>in</code> <code>range</code><code>(</code><code>len</code><code>(arr)):</code>
<code> </code><code>arr[i] </code><code>=</code> <code>-</code><code>arr[i]</code>
<code> </code><code>arr </code><code>=</code> <code>multiprocessing.Array(</code><code>'i'</code><code>, </code><code>range</code><code>(</code><code>10</code><code>))</code>
<code> </code><code>print</code> <code>(arr[:])</code>
<code> </code><code>p3 </code><code>=</code> <code>multiprocessing.Process(target</code><code>=</code><code>change,args</code><code>=</code><code>(arr,))</code>
<code> </code><code>p3.start()</code>
<code> </code><code>p3.join()</code>
<code>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</code>
<code>[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]</code>
<code>init add1 number = 15</code>
<code>add1 number = 16</code>
<code>add1 number = 17</code>
<code>add1 number = 18</code>
<code>add1 number = 19</code>
<code>add1 number = 20</code>
版權聲明:原創作品,如需轉載,請注明出處。否則将追究法律責任
本文轉自 聽丶飛鳥說 51CTO部落格,原文連結:http://blog.51cto.com/286577399/2049535