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 - 使用脚本从父级到子级共享变量的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章

在 AngularJS 组件中从父级到子级通信事件

VueJS 2.0 从父级到子级的通信

在 ReactJs 中,从 redux 存储或从父级到子级将 props 传递给子组件的最佳实践是啥?

如何使引导树视图从父级折叠到子级?

数据未在 VueJS 中使用提供/注入从父级注入到子级

如何从父级获取数据到子级?