Lock组件
当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,
如果两个文件同时进行,肯定是不行的,必须是文件写结束后,才可以进行读操作。
或者是多个进程在共享一些资源的时候,同时只能有一个进程进行访问,那就需要锁机制进行控制。
需求:
一个进程写入一个文件,一个进程追加文件,一个进程读文件,同时启动起来
我们可以通过进程的join()方法来实现,这是一种方法,本节用Lock(进程锁)来实现。
函数说明:
# lock = multiprocessing.Lock()
# lock.acquire() #获得锁
# lock.release() #释放锁
先写不加锁的程序:
#不加锁
# number +1
# number +3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import
multiprocessing
import
time
def
add(number,value,lock):
print
(
"init add{0} number = {1}"
.
format
(value, number))
for
i
in
xrange
(
1
,
6
):
number
+
=
value
time.sleep(
1
)
print
(
"add{0} number = {1}"
.
format
(value, number))
if
__name__
=
=
"__main__"
:
lock
=
multiprocessing.Lock()
number
=
0
p1
=
multiprocessing.Process(target
=
add,args
=
(number,
1
, lock))
p2
=
multiprocessing.Process(target
=
add,args
=
(number,
3
, lock))
p1.start()
p2.start()
print
(
"main end"
)
|
结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
main end
init add1 number = 0
init add3 number = 0
add1 number = 1
add3 number = 3
add1 number = 2
add3 number = 6
add1 number = 3
add3 number = 9
add1 number = 4
add3 number = 12
add1 number = 5
add3 number = 15
|
再写加锁的程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
multiprocessing
import
time
def
add(number,value,lock):
with lock:
print
(
"init add{0} number = {1}"
.
format
(value, number))
for
i
in
xrange
(
1
,
6
):
number
+
=
value
time.sleep(
1
)
print
(
"add{0} number = {1}"
.
format
(value, number))
if
__name__
=
=
"__main__"
:
lock
=
multiprocessing.Lock()
number
=
0
p1
=
multiprocessing.Process(target
=
add,args
=
(number,
1
, lock))
p2
=
multiprocessing.Process(target
=
add,args
=
(number,
3
, lock))
p1.start()
p2.start()
print
(
"main end"
)
|
结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
main end
init add1 number = 0
#add1优先抢到锁,优先执行
add1 number = 1
add1 number = 2
add1 number = 3
add1 number = 4
add1 number = 5
init add3 number = 0
#add3被阻塞,等待add1执行完成,释放锁后执行add3
add3 number = 3
add3 number = 6
add3 number = 9
add3 number = 12
add3 number = 15
|
使用 lock.acquire() 和 lock.release()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import
multiprocessing
import
time
def
add(number,value,lock):
lock.acquire()
try
:
print
(
"init add{0} number = {1}"
.
format
(value, number))
for
i
in
xrange
(
1
,
6
):
number
+
=
value
time.sleep(
1
)
print
(
"add{0} number = {1}"
.
format
(value, number))
except
Exception as e:
raise
e
finally
:
lock.release()
if
__name__
=
=
"__main__"
:
lock
=
multiprocessing.Lock()
number
=
0
p1
=
multiprocessing.Process(target
=
add,args
=
(number,
1
, lock))
p2
=
multiprocessing.Process(target
=
add,args
=
(number,
3
, lock))
p1.start()
p2.start()
print
(
"main end"
)
|
结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
main end
init add1 number
=
0
add1 number
=
1
add1 number
=
2
add1 number
=
3
add1 number
=
4
add1 number
=
5
init add3 number
=
0
add3 number
=
3
add3 number
=
6
add3 number
=
9
add3 number
=
12
add3 number
=
15
|
共享内存
python的multiprocessing模块也给我们提供了共享内存的操作
一般的变量在进程之间是没法进行通讯的,multiprocessing 给我们提供了 Value 和 Array 模块,他们可以在不通的进程中共同使用
例子:不加锁,让number加完1后再继续加3,再继续加一,再继续加3...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import
multiprocessing
import
time
def
add(number,add_value):
try
:
print
(
"init add{0} number = {1}"
.
format
(add_value, number.value))
for
i
in
xrange
(
1
,
6
):
number.value
+
=
add_value
print
(
"***************add{0} has added***********"
.
format
(add_value))
time.sleep(
1
)
print
(
"add{0} number = {1}"
.
format
(add_value, number.value))
except
Exception as e:
raise
e
if
__name__
=
=
"__main__"
:
number
=
multiprocessing.Value(
'i'
,
0
)
p1
=
multiprocessing.Process(target
=
add,args
=
(number,
1
))
p2
=
multiprocessing.Process(target
=
add,args
=
(number,
3
))
p1.start()
p2.start()
print
(
"main end"
)
|
打印结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
main end
init add1 number
=
0
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add1 has added
*
*
*
*
*
*
*
*
*
*
*
init add3 number
=
1
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add3 has added
*
*
*
*
*
*
*
*
*
*
*
add1 number
=
4
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add1 has added
*
*
*
*
*
*
*
*
*
*
*
add3 number
=
5
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add3 has added
*
*
*
*
*
*
*
*
*
*
*
add1 number
=
8
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add1 has added
*
*
*
*
*
*
*
*
*
*
*
add3 number
=
9
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add3 has added
*
*
*
*
*
*
*
*
*
*
*
add1 number
=
12
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add1 has added
*
*
*
*
*
*
*
*
*
*
*
add3 number
=
13
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add3 has added
*
*
*
*
*
*
*
*
*
*
*
add1 number
=
16
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add1 has added
*
*
*
*
*
*
*
*
*
*
*
add3 number
=
17
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
add3 has added
*
*
*
*
*
*
*
*
*
*
*
add1 number
=
20
add3 number
=
20
|
再给加上锁:
加1的进程加完后,再执行加上3的进程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import
multiprocessing
import
time
def
add(number,add_value,lock):
lock.acquire()
try
:
print
(
"init add{0} number = {1}"
.
format
(add_value, number.value))
for
i
in
xrange
(
1
,
6
):
number.value
+
=
add_value
print
(
"***************add{0} has added***********"
.
format
(add_value))
time.sleep(
1
)
print
(
"add{0} number = {1}"
.
format
(add_value, number.value))
except
Exception as e:
raise
e
finally
:
lock.release()
if
__name__
=
=
"__main__"
:
lock
=
multiprocessing.Lock()
number
=
multiprocessing.Value(
'i'
,
0
)
p1
=
multiprocessing.Process(target
=
add,args
=
(number,
1
, lock))
p2
=
multiprocessing.Process(target
=
add,args
=
(number,
3
, lock))
p1.start()
p2.start()
print
(
"main end"
)
|
执行结果(对比上面):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
main end
init add1 number = 0
***************add1 has added***********
add1 number = 1
***************add1 has added***********
add1 number = 2
***************add1 has added***********
add1 number = 3
***************add1 has added***********
add1 number = 4
***************add1 has added***********
add1 number = 5
init add3 number = 5
***************add3 has added***********
add3 number = 8
***************add3 has added***********
add3 number = 11
***************add3 has added***********
add3 number = 14
***************add3 has added***********
add3 number = 17
***************add3 has added***********
add3 number = 20
|
多进程共享内存实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import
multiprocessing
import
time
def
add(number,add_value,lock):
lock.acquire()
try
:
print
(
"init add{0} number = {1}"
.
format
(add_value, number.value))
for
i
in
xrange
(
1
,
6
):
number.value
+
=
add_value
print
(
"***************add{0} has added***********"
.
format
(add_value))
time.sleep(
1
)
print
(
"add{0} number = {1}"
.
format
(add_value, number.value))
except
Exception as e:
raise
e
finally
:
lock.release()
def
change(arr):
for
i
in
range
(
len
(arr)):
arr[i]
=
-
arr[i]
if
__name__
=
=
"__main__"
:
lock
=
multiprocessing.Lock()
number
=
multiprocessing.Value(
'i'
,
0
)
arr
=
multiprocessing.Array(
'i'
,
range
(
10
))
print
(arr[:])
p1
=
multiprocessing.Process(target
=
add,args
=
(number,
1
, lock))
p2
=
multiprocessing.Process(target
=
add,args
=
(number,
3
, lock))
p3
=
multiprocessing.Process(target
=
change,args
=
(arr,))
p1.start()
p2.start()
p3.start()
p3.join()
print
(arr[:])
print
(
"main end"
)
|
结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
init add3 number = 0
***************add3 has added***********
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
main end
add3 number = 3
***************add3 has added***********
add3 number = 6
***************add3 has added***********
add3 number = 9
***************add3 has added***********
add3 number = 12
***************add3 has added***********
add3 number = 15
init add1 number = 15
***************add1 has added***********
add1 number = 16
***************add1 has added***********
add1 number = 17
***************add1 has added***********
add1 number = 18
***************add1 has added***********
add1 number = 19
***************add1 has added***********
add1 number = 20
|
版权声明:原创作品,如需转载,请注明出处。否则将追究法律责任
本文转自 听丶飞鸟说 51CTO博客,原文链接:http://blog.51cto.com/286577399/2049535