◎知识点
进程间通信之共享内存
多进程操作共享数据的不安全性
多线程操作共享数据的不安全性
◎脚本练习
▽ 进程间通信之共享内存
"""
如果想要实现进程之间的通信,共享内存是常见的实现方式之一。它允许多个进程直接访问同一块内存。
共享内存中对象的类型必须是ctypes的。ctypes是与C语言兼容的数据类型。
为了在共享内存中创建ctypes类型的对象,标准库模块multiprocessing提供了如下两个函数:
(1) Value(typecode_or_type: Any, *args: Any, lock: bool = ...) -> sharedctypes._Value: ...
返回值表示一个数值。
参数typecode_or_type用于指定数值的类型码或ctypes类型。
(2) def Array(typecode_or_type: Any, size_or_initializer: Union[int, Sequence[Any]], *, lock: bool = ...)
返回值表示一个数组。
参数typecode_or_type用于指定数组中元素的类型码或ctypes类型。
参数size_or_initializer用于指定数组的长度或python中的序列。
"""
from multiprocessing import Process, Value, Array
import ctypes
def do_sth0(number, array):
number.value = 1.8
for i in range(len(array)):
array[i] = -array[i]
if __name__ == '__main__':
# 在共享内存中创建一个表示数值的ctypes对象
number = Value('d', 2.3)
# <Synchronized wrapper for c_double(2.3)>
array = Array('i', range(1, 5))
# <SynchronizedArray wrapper for <multiprocessing.sharedctypes.c_int_Array_4 object at 0x10f43f3c0>>
p = Process(target=do_sth0, args=(number, array))
p.start()
p.join()
print(number.value) # 1.8
print(array[:]) # [-1, -2, -3, -4]▽ 多进程操作共享数据的不安全性
"""
由于多进程的执行是不确定的,导致多进程操作共享数据的结果是不可预期的,常被称为不安全的。
"""
from multiprocessing import Process, Value, Array
def do_sth(num):
for i in range(100):
# 相当于:num.value = num.value + 1
# 首先计算num.value + 1,存入临时变量中,然后将临时变量的值赋给num
num.value += 1
def do_sth1(arr):
for i in range(len(arr)):
arr[i] = -arr[i]
if __name__ == '__main__':
num = Value('i', 0)
arr = Array('i', range(10))
p1 = Process(target=do_sth, args=(num,))
p2 = Process(target=do_sth, args=(num,))
p3 = Process(target=do_sth1, args=(arr,))
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
print(num.value) # not sure
print(arr[:]) # [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]▽ 多线程操作共享数据的不安全性
""" 由于多线程的执行是不确定的,导致多线程操作共享数据的结果是不可预期的,常被称为不安全的。 """ from threading import Thread num2 = 0 def do_sth2(): global num2 for i in range(100000): num2 += 1 if __name__ == '__main__': t1 = Thread(target=do_sth2) t2 = Thread(target=do_sth2) t1.start() t2.start() t1.join() t2.join() print(num2) # not sure

