天天看點

37. Python 多程序鎖 多程序共享記憶體

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