2

指定されたすべてのパスのサイズを計算する、次の抜粋されたコードを検討してください。

def pathSizes = []
paths.each { rootPath ->
  pathSizes.addAll(
    withPool { pool ->
      runForkJoin(rootPath) { path ->
        def headSizes = [:]
        println path

        def lines = ["ls", "-al", path].execute().text.readLines()
        (0..<3).each { lines.remove(0) }
        lines.each { line ->
          def fields = line.split(/\s+/)
          if (fields[0] =~ /^d/)
            forkOffChild("$path/${fields.last()}")
          else {
            def userName = fields[2]
            def fileSize = fields[4] as long
            if (headSizes[userName] == null)
              headSizes[userName] = fileSize
            else
              headSizes[userName] += fileSize
          }
        }

        quietlyJoin()
        System.gc()

        def shallowSizes =
          headSizes.collectEntries { userName, fileSize ->
            def childResult =
              childrenResults.sum {
                 it.shallowSizes[userName] ? it.shallowSizes[userName] : 0
              } ?: 0
            return [userName, fileSize + childResult]
          }

        def deepSizes =
          childrenResults.sum { it.deepSizes ?: [] } +
          shallowSizes.collect { userName, fileSize ->
            [userName: userName, path: path, fileSize: fileSize]
          }

        return [shallowSizes: shallowSizes, deepSizes: deepSizes]
      }.deepSizes
    })
}

このコード スニペットがデッドロックになるのはなぜですか? システム コールと Java フレームワークの他の部分を除いて、スレッド間の相互作用はありません。システム コールが問題である場合、システム コールを削除せずにどのように修正できますか (システム コールは遅いため、並列化する必要があります)。

4

0 に答える 0