python使用mmap模块完成内存映射与进程间通信

import mmap

# 创建一个文件
with open('hello.txt', 'wb') as f:
    f.write(b"Hello Python!\n")
with open('hello.txt', 'r+b') as f:
    # mmap基本上接收两个参数,(文件描述符,读取长度),size 为0表示读取整个文件
    mm = mmap.mmap(f.fileno(), 0)
    # 标准读取方式
    print(mm.readline())  # prints "Hello Python!"
    # 切片读取方式
    print(mm[:5])  # prints "Hello"
    # 切片方式改变文件内容;
    # 注意size长度匹配
    mm[6:] = b" world!\n"
    # 使用seek定位光标到数据头,当前光标已到数据末(mm.tell()可获取当前光标)
    mm.seek(0)
    # 再次标准读取
    print(mm.readline())  # prints "Hello  world!"
    # 像处理文件一样关闭mmap映射
    mm.close()

输出结果

b’Hello Python!\n’
b’Hello’
b’Hello world!\n’

使用mmap完成共享内存方式的进程间通信

import mmap
import os
import time

mm = mmap.mmap(-1, 27)
mm.write(b"Original msg") # 涉及mm的读写都要记得字符串的二进制
print('write successfully')

pid = os.fork()

if pid == 0:  # 子进程中
    mm.seek(0)
    print('Read from the mmap:')
    print(mm.readline())
    #以切片访问时,严格按照字符串长度
    mm[12:] =  b' sth from child'
    mm.close()
else:
    time.sleep(2)# 用sleep使子进程先执行
    mm.seek(0)
    print('Read from the child:')
    print(mm.readline())
    mm.close()

输出

write successfully
Read from the mmap:
b’Original msg\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00’
Read from the child:
b’Original msg sth from child’

当年理解fork花了不少时间,与其说父子进程,不如说兄弟进程.
从英文版入手,fork本身就是分叉的意思.运行到fork便分叉运行.这样理解自然更容易入手.
共享内存主要基于两点:
1) 子进程继承父进程的变量的副本;
2) mmap返回指向文件的指针,本来在子进程中操作的变量是不会影响父进程的.但是因为mmap代表的是一种映射关系. 犹如从fork切换到子进程时,给子进程复制了一把指向与父进程同一块内存的钥匙,虽然两把钥匙是独立的,但是凭借两把钥匙,两个进程可以在同一个内存区域上进行修改,从而完成进程间通信.

随手记: 凡是计算机的概念理解都不能脱离代码,即使API封装程度已经很高,实现一遍也会有收货.从前只是通过概念学习进程间通信,如今通过代码可以加深理解.

猜你喜欢

转载自blog.csdn.net/m0_37422289/article/details/79895526