并行线程上的会话ID问题

时间:2017-11-14 15:05:35

标签: python session python-multiprocessing pool

所以我尝试使用 multiprocessing 来同时迭代单独文件夹中的文件。我有一个调用并行进程的函数:

from multiprocessing.dummy import Pool

lsFolders = ['Folder1', 'Folder2']

pool = Pool( processes = 6 )

iterateThroughFiles = IterateThroughFiles() # instantiated by call to pool.map()

pool.map( iterateThroughFiles.runProcess, lsFolders )

然后我实现了 IterateThroughFiles -class:

class IterateThroughFiles( object ):

  def runProcess( self, folder ):
      self.sessionId = uuid.uuid4()
      print( self.sessionId )             # Prints a correct sessionId
      logAtLevel( "INFO", "Session ID of: "
                         + str( self.sessionId )
                         + " has been generated for folder: "
                         + folder
                           )

      print( self.sessionId )             # Prints only the second generated
      #                                   # session id for both threads
      print( folder )                     # Prints the correct folder

当我生成 sessionId 并在之后直接打印时,sessionId是正确的,另外 logAtLevel() 包装函数记录sessionId的正确值。

但是,下一个print语句只打印第二个会话ID,显然在帖子中忘记了第一个sessionId

有谁知道为什么会这样?我认为当并行运行时,每个线程在创建的对象和内存方面都是不同的?这是不正确的?这与uuid发生器有关吗?

2 个答案:

答案 0 :(得分:2)

问题是您只生成一个IterateThroughFiles实例,该实例正在两个线程中使用。 相反,你需要类似下面的内容

def factory(folder):
    return IterateThroughFiles().runProcess(folder)

并将该工厂函数传递给地图。 这样你就会得到两个实例。

答案 1 :(得分:1)

  

pool.map(iterateThroughFiles.runProcess, lsFolders)

在这一行中,您在类IterateThroughFiles的单个实例上多次调用runProcess。如果您将每个实例视为会话,则需要为lsFolders中的每个文件夹实例化一个新对象。

from multiprocessing.dummy import Pool

lsFolders = ['Folder1', 'Folder2']

pool = Pool(processes=6)

def worker(folder):
    p = IterateThroughFiles()
    p.runProcess(folder)

pool.map(worker, lsFolders)

这样,worker函数为每个文件夹创建一个IterateThroughFiles的新实例,在runProcess函数中,self指的是那个单独的实例,而不是为每个文件夹使用相同的实例。