2016-06-16 10 views
0

私が書いているこのGoコードの終わりにデッドロックエラーが発生する理由を知るには誰も助けてくれますか?プログラムは実際には正常に動作しますが、デッドロックエラーが発生します。私はコンカレントコードを書くのが初めてで、どんな助けでも大歓迎です。私は読んですぐにそれを問題にしないと分かっている行を省略しました。Golang並行デッドロック

func MoveWorksheets(worksheetList []string) { 

var wg sync.WaitGroup 

for _, worksheet := range worksheetList { 

    wg.Add(1) 

    go MoveFile(src, dst, wg) 

    } 

    wg.Wait() 
} 

func MoveFile(src, dst string, wg sync.WaitGroup) (err error) { 

    defer wg.Done() 

    sfi, err := os.Stat(src) 
    if err != nil { 
     return 
    } 
    if !sfi.Mode().IsRegular() { 
     // cannot copy non-regular files (e.g., directories, 
     // symlinks, devices, etc.) 
     return fmt.Errorf("CopyFile: non-regular source file %s (%q)", sfi.Name(), sfi.Mode().String()) 
    } 
    dfi, err := os.Stat(dst) 
    if err != nil { 
     if !os.IsNotExist(err) { 
      return 
     } 
    } else { 
     if !(dfi.Mode().IsRegular()) { 
      return fmt.Errorf("CopyFile: non-regular destination file %s (%q)", dfi.Name(), dfi.Mode().String()) 
     } 
     if os.SameFile(sfi, dfi) { 
      return 
     } 
    } 
    /*if err = os.Link(src, dst); err == nil { 
     return 
    }*/ 
    err = MoveFileContents(src, dst) 
    return 
} 

func MoveFileContents(src, dst string) (err error) { 

    merr := os.Rename(src, dst) 

    if merr != nil { 
     log.Fatal(merr) 
    } 

    return 
} 
+0

スタックトレースは、ブロックする場所を示す必要があります。出力は何ですか? – JimB

+0

致命的なエラー:すべてのゴルーチンが眠っています - デッドロックです! ゴルーチン1 [semacquire]: sync.runtime_Semacquire(0xc08200274c) C:/Go/src/runtime/sema.go:47 + 0x2d 同期(* WaitGroup).WAIT(0xc082002740) C:/ GO/SRC /同期/ waitgroup.go:127 + 0xbb main.MoveWorksheets(0xc08200a400、0x14に、0x20の) C:/code/src/github.com/deisun/adminsorter/adminsorterc.go:162 +は0x27 main.Run( ) C:/code/src/github.com/deisun/adminsorter/adminsorterc.go:40 + 0xa6 main.main() C:/code/src/github.com/deisun/adminsorter/adminsorterc.go: 26 + 0x46 – Deisun

+0

ところで、 'go vet'はこのエラーをキャッチします。 – JimB

答えて

1

MoveFilewgのコピーを取得しているので、あなたは別のWaitGroupの上Wait()Done()を呼んでいます。ポインタとして渡してみてください。

+0

うわー、それは...ありがとう!私はばかだ、私はそれを考えなかったと信じることができない。 – Deisun

0

wg変数の参照をコード内で試してみてください。MoveFile関数がWaitGroupの独自のコピーを取得しています。それがデッドロックを作り出す理由です。

func MoveWorksheets(worksheetList []string) { 

     var wg sync.WaitGroup 

     for _, worksheet := range worksheetList { 

      wg.Add(1) 

      go MoveFile(src, dst, &wg) 

     } 

     wg.Wait() 
    } 

    func MoveFile(src, dst string, wg *sync.WaitGroup) (err error) { 

     defer wg.Done() 

     sfi, err := os.Stat(src) 
     if err != nil { 
      return 
     } 
     if !sfi.Mode().IsRegular() { 
      // cannot copy non-regular files (e.g., directories, 
      // symlinks, devices, etc.) 
      return fmt.Errorf("CopyFile: non-regular source file %s (%q)", sfi.Name(), sfi.Mode().String()) 
     } 
     dfi, err := os.Stat(dst) 
     if err != nil { 
      if !os.IsNotExist(err) { 
       return 
      } 
     } else { 
      if !(dfi.Mode().IsRegular()) { 
       return fmt.Errorf("CopyFile: non-regular destination file %s (%q)", dfi.Name(), dfi.Mode().String()) 
      } 
      if os.SameFile(sfi, dfi) { 
       return 
      } 
     } 
     /*if err = os.Link(src, dst); err == nil { 
      return 
     }*/ 
     err = MoveFileContents(src, dst) 
     return 
    } 

    func MoveFileContents(src, dst string) (err error) { 

     merr := os.Rename(src, dst) 

     if merr != nil { 
      log.Fatal(merr) 
     } 

     return 
    } 
関連する問題