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