title: How to solve fatal error: concurrent map read and map write
body: <p>I'm writing some program in Go, I get this crash:</p>
  
  <pre><code>fatal error: concurrent map read and map write
  
  
  consensus/bft.(*ConsensusManager).getHeightManager(0xc42009a7e0, 0x37, 0x0)
  
  consensus/bft/bft_manager.go:246 +0x9b fp=0xc42b033258 sp=0xc42b033208 pc=0xaf1d7b
  consensus/bft.(*HeightManager).Round(...)
  consensus/bft/bft_manager.go:239
  consensus/bft.(*ConsensusManager).Round(0xc42009a7e0, 0x37)
  </code></pre>
  
  <p>This is my code</p>
  
  <pre><code>type ConsensusManager struct {
      pm                      *ProtocolManager
      chain                   *core.BlockChain
      coinbase                common.Address
      readyValidators         map[common.Address]struct{}
      trackedProtocolFailures []string
      heights                 map[uint64]*HeightManager
      blockCandidates         map[common.Hash]btypes.Proposal
  
      currentBlock *types.Block
      found        chan *types.Block
  
      mu          sync.Mutex
      writeMapMu  sync.RWMutex
      getHeightMu sync.RWMutex
      processMu sync.Mutex
  }
  func (cm *ConsensusManager) Round() uint64 {
      return cm.getHeightManager(cm.Height()).Round()
  }
  
  func (cm *ConsensusManager) getHeightManager(h uint64) *HeightManager {
  
      if _, ok := cm.heights[h]; !ok {
          cm.heights[h] = NewHeightManager(cm, h)
      }
  
      return cm.heights[h]
  }
  </code></pre>
  
  <p>I try to Use RWMutex to Luck, but the code can't  work </p>
  
  <pre><code>func (cm *ConsensusManager) Round() uint64 {
          cm.getHeightMu.Lock()
      defer cm.getHeightMu.Unlock()
  
      return cm.getHeightManager(cm.Height()).Round()
  }
  
  func (cm *ConsensusManager) getHeightManager(h uint64) *HeightManager {
          cm.getHeightMu.Lock()
      defer cm.getHeightMu.Unlock()
  
          if _, ok := cm.heights[h]; !ok {
          cm.heights[h] = NewHeightManager(cm, h)
      }
  
      return cm.heights[h]
  }
  
  </code></pre>
  
  <p>What's wrong with my solutions?</p>