面试题答案
一键面试1. 使用共享内存实现内存共享
在Python的multiprocessing
模块中,可以使用Value
和Array
来实现简单的共享内存。
import multiprocessing
def worker(num):
num.value = num.value * 2
if __name__ == '__main__':
shared_num = multiprocessing.Value('i', 5)
p = multiprocessing.Process(target=worker, args=(shared_num,))
p.start()
p.join()
print(shared_num.value)
这里multiprocessing.Value
创建了一个共享的数值对象,'i'
表示整数类型。Array
用于创建共享的数组。
2. 使用mmap
实现内存共享
mmap
模块允许在Python中使用内存映射文件。
import mmap
import multiprocessing
def worker(mmap_obj):
with mmap_obj:
mmap_obj.write(b'Hello, from worker')
if __name__ == '__main__':
with open('temp.txt', 'w+b') as f:
f.write(b' ' * 100)
mmap_obj = mmap.mmap(f.fileno(), 0)
p = multiprocessing.Process(target=worker, args=(mmap_obj,))
p.start()
p.join()
mmap_obj.seek(0)
print(mmap_obj.readline())
mmap_obj.close()
这里创建了一个临时文件并将其映射到内存,多个进程可以通过这个内存映射对象进行数据共享。
3. 内存一致性问题
- 缓存一致性:不同进程可能有自己的缓存,对共享内存的修改不会立即在其他进程的缓存中可见。例如,一个进程修改了共享内存中的数据,但另一个进程读取时可能仍然得到旧值。
- 读写竞争:多个进程同时读写共享内存可能导致数据不一致。比如一个进程正在写入数据,另一个进程同时读取,可能读取到部分修改的数据。
4. 解决策略
- 锁机制:使用
multiprocessing.Lock
来防止多个进程同时访问共享内存。
import multiprocessing
def worker(shared_num, lock):
with lock:
shared_num.value = shared_num.value * 2
if __name__ == '__main__':
shared_num = multiprocessing.Value('i', 5)
lock = multiprocessing.Lock()
p = multiprocessing.Process(target=worker, args=(shared_num, lock))
p.start()
p.join()
print(shared_num.value)
- 信号量:
multiprocessing.Semaphore
可以控制同时访问共享资源的进程数量。如果允许最多3个进程同时访问共享内存,可以创建一个值为3的信号量。
import multiprocessing
def worker(shared_num, semaphore):
with semaphore:
shared_num.value = shared_num.value * 2
if __name__ == '__main__':
shared_num = multiprocessing.Value('i', 5)
semaphore = multiprocessing.Semaphore(3)
processes = []
for _ in range(5):
p = multiprocessing.Process(target=worker, args=(shared_num, semaphore))
processes.append(p)
p.start()
for p in processes:
p.join()
print(shared_num.value)
- 使用原子操作:对于简单数据类型,使用
multiprocessing.Value
提供的原子操作可以避免一些竞争条件。例如Value
对象的value
属性的赋值操作是原子的。