python3 - 使用脚本从父级到子级共享变量的最简单方法
Posted
技术标签:
【中文标题】python3 - 使用脚本从父级到子级共享变量的最简单方法【英文标题】:python3 - easiest way to share variable from parent to child using scripts 【发布时间】:2020-03-30 18:03:40 【问题描述】:使用脚本 parent.py 我想设置变量 parvar
并执行 child.py 并打印 parvar
。我很难用最简单的方法来实现这一点。似乎我可以使用 os.fork() 作为父母中存在的数据呈现给孩子,但我无法让它工作。阅读使用多处理的示例,我找不到显示跨两个不同脚本共享数据的示例。
这是我目前所拥有的:
parent.py
#!/usr/bin/env python3
import subprocess, os
parvar = 'parent var'
pid = os.fork()
if pid == 0:
print('child pid is running')
subprocess.call(['python3', 'child.py'])
exit()
child.py
#!/usr/bin/env python3
childvar = 'child var'
print('this is child var: ', childvar)
print(parvar)
返回 NameError:
$ ./parent.py
child pid is running
$ this is child var: child var
Traceback (most recent call last):
File "child.py", line 4, in <module>
print(parvar)
NameError: name 'parvar' is not defined
我想我明白为什么这不起作用。 subprocess
调用替换现有进程 - 生成一个新进程。因为那不是分叉的,所以我提供给我的孩子 PID 的任何东西现在都无法被第三个进程访问。
有人可以帮我举一个简单的例子来让上面的工作正常吗?
【问题讨论】:
【参考方案1】:这不是一个答案(至少现在还不是),但我想我会在这里发布这个,因为它似乎使事情朝着正确的方向发展。
使用此页面中的 mmap 示例:
https://blog.schmichael.com/2011/05/15/sharing-python-data-between-processes-using-mmap/
我已经(我相信正确)为 Python 3 (3.6.8) 重构了它:
a.py
#!/usr/bin/env python3
import ctypes
import mmap
import os
import struct
def main():
# Create new empty file to back memory map on disk
fd = os.open('/tmp/mmaptest', os.O_CREAT | os.O_TRUNC | os.O_RDWR)
# Zero out the file to insure it's the right size
assert os.write(fd, b'\x00' * mmap.PAGESIZE) == mmap.PAGESIZE
# Create the mmap instace with the following params:
# fd: File descriptor which backs the mapping or -1 for anonymous mapping
# length: Must in multiples of PAGESIZE (usually 4 KB)
# flags: MAP_SHARED means other processes can share this mmap
# prot: PROT_WRITE means this process can write to this mmap
buf = mmap.mmap(fd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_WRITE)
# Now create an int in the memory mapping
i = ctypes.c_int.from_buffer(buf)
# Set a value
i.value = 10
# And manipulate it for kicks
i.value += 1
assert i.value == 11
# Before we create a new value, we need to find the offset of the next free
# memory address within the mmap
offset = struct.calcsize(i._type_)
# The offset should be uninitialized ('\x00')
assert buf[offset] == 0
# Now ceate a string containing 'foo' by first creating a c_char array
s_type = ctypes.c_char * len('foo')
# Now create the ctypes instance
s = s_type.from_buffer(buf, offset)
# And finally set it
s.raw = b'foo'
print('First 10 bytes of memory mapping: %r' % buf[:10])
input('Now run b.py and press ENTER')
print
print('Changing i')
i.value *= i.value
print('Changing s')
s.raw = b'bar'
new_i = input('Enter a new value for i: ')
i.value = int(new_i)
if __name__ == '__main__':
main()
b.py
#!/usr/bin/env python3
import mmap
import os
import struct
import time
def main():
# Open the file for reading
fd = os.open('/tmp/mmaptest', os.O_RDONLY)
# Memory map the file
buf = mmap.mmap(fd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_READ)
i = None
s = None
while 1:
new_i, = struct.unpack('i', buf[:4])
new_s, = struct.unpack('3s', buf[4:7])
if i != new_i or s != new_s:
print('i: %s => %d' % (i, new_i))
print('s: %s => %s' % (s, new_s))
print('Press Ctrl-C to exit')
i = new_i
s = new_s
time.sleep(1)
if __name__ == '__main__':
main()
执行示例
1 号航站楼
$ ./a.py
First 10 bytes of memory mapping: b'\x0b\x00\x00\x00foo\x00\x00\x00'
Now run b.py and press ENTER
Changing i
Changing s
Enter a new value for i: 87
2号航站楼
$ ./b.py
i: None => 11
s: None => b'foo'
Press Ctrl-C to exit
i: 11 => 121
s: b'foo' => b'bar'
Press Ctrl-C to exit
i: 121 => 87
s: b'bar' => b'bar'
Press Ctrl-C to exit
【讨论】:
以上是关于python3 - 使用脚本从父级到子级共享变量的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章