在进程内创建父对象时,Python多线程不使用公共内存

2024-04-25 19:56:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试实现一个线程,它将在后台运行并执行任务。下面是我的代码,它给出了预期的输出。你知道吗

代码1:

from time import sleep
from threading import Thread

class myTest( ):
    def myThread( self ):
        while True:
            sleep( 1 )
            print self.myList.keys( )
            if 'exit' in self.myList.keys( ):
                break
        return

    def __init__( self ):
        self.myList = { } 
        self.thread = Thread( target = self.myThread, args = (  ) )
        self.thread.start( )
        return

    def myFun( self ):
        i = 0
        while True:
            sleep( 0.5 )
            self.myList[ i ] = i
            i += 1
            if i > 5 :
                self.myList[ 'exit' ] = ''
                break
        return

x = myTest( )
x.myFun( )

输出1:

[0]
[0, 1, 2]
[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4, 5, 'exit']

当我创建一个多进程环境并在新的子进程中创建这个对象时,线程就无法访问公共内存,并且线程中的字典myList仍然是空的。这是密码。你知道吗

代码2:

from time import sleep
from threading import Thread
from multiprocessing import Process

class myTest( ):
    def myThread( self ):
        while True:
            sleep( 1 )
            print "myThread", self.myList.keys( )
            if 'exit' in self.myList.keys( ):
                break
        return

    def __init__( self ):
        self.myList = { } 
        self.thread = Thread( target = self.myThread, args = (  ) )
        self.thread.start( )
        self.i = 0
        return

    def myFun( self ):
        self.myList[ self.i ] = self.i
        self.i += 1
        if self.i > 5 :
            self.myList[ 'exit' ] = ''
            return 'exit'
        print 'myFun', self.myList.keys( )
        return

class myProcess( Process ):
    def __init__( self ):
        super( myProcess, self ).__init__( )
        self.myObject = myTest( )
        return

    def run(self):
        while True:
            sleep( 0.5 )
            x = self.myObject.myFun( )
            if x == 'exit':
                break
        return

x = myProcess( )
x.start( )

输出2:

myFun [0]
myThread []
myFun [0, 1]
myFun [0, 1, 2]
myThread []
myFun [0, 1, 2, 3]
myFun [0, 1, 2, 3, 4]
myThread []
myThread []
myThread []
... ... ...
... ... ...

在第一段代码中,对象是在Python进程(尽管是主进程)中创建的。在第二段代码中,对象是在Python的子进程中创建的,在这个子进程中,所有事情都会发生,它们的行为应该与第一个进程一样。你知道吗

  1. 有人能解释为什么在第二段代码中,线程不能使用父对象的共享内存吗?你知道吗
  2. 我想要output 1中的code 2,即强制线程使用父对象的共享公共内存。我需要做什么修改?你知道吗

Tags: 代码fromimportselfreturnif进程def
2条回答

分叉进程在fork()时刻看到父内存的快照。当父级或子级更改一个位时,它们的内存映射会发生分歧,一个看到它更改了什么,另一个看到旧状态。在这个答案中,我对这个理论的解释更加详细:https://stackoverflow.com/a/29838782/73957

如果你想共享内存[更改],你必须隐式地这样做。在Python中,一种简单的方法是multiprocessing.{Queue,Value,Array},请参见https://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes

生成第二个进程时,将创建第一个进程的副本,因此在第二个进程中生成的线程只能访问该进程堆栈。你知道吗

code2中,myTest的对象是在构造函数(__init__)中创建的,因此它不会与派生进程run共享相同的内存。只需将对象创建的位置从构造函数更改为run,所创建的对象就成为派生进程内存的一部分。你知道吗

相关问题 更多 >