title: Understanding Put/Get in mpi4py
body: <p>I'm learning how to use one-sided communication in mpi4py. To test my understanding, I came up with this contrived example:</p>
  
  <pre><code>import mpi4py.MPI as mpi
  import numpy as np
  import time
  
  def main():
      rank = mpi.COMM_WORLD.Get_rank()
      n_proc = mpi.COMM_WORLD.Get_size()
  
      assert(n_proc == 2)
  
      buff = np.zeros(10, dtype='d')
      win = mpi.Win.Create(buff, 1, mpi.INFO_NULL, mpi.COMM_WORLD)
  
      if (rank == 0):
          win.Lock(1)
          win.Put([buff, mpi.DOUBLE], 1)
          win.Unlock(1)
  
          buff[-1] = 9
          time.sleep(30)
  
          win.Lock(1)
          win.Put([buff, mpi.DOUBLE], 1)
          win.Unlock(1)
  
      else:
          holder = np.zeros(10)
          failures = 0
          while (holder[-1] != 9):
              failures += 1
              win.Lock(0)
              win.Get([holder, mpi.DOUBLE], 0)
              win.Unlock(0)
          print('Took', failures, 'dials')
  
  if __name__=='__main__':
      main()
  </code></pre>
  
  <p>I expect this to work as follows: rank 0 will wait for 30 seconds before placing the ndarray containing <code>[0, 0, ..., 0, 9]</code> into the shared memory. Meanwhile, rank 1 will continuously check to see if rank 0 has updated its shared memory---once it has, it will print out what it sees. Specifically, <em>I would expect that rank 1 would execute its while loop many many times</em> during the 30 second wait while rank 0 is idle. However, when I run this code with <code>mpirun -n 2 python mwe.py</code>, I consistently get this output:</p>
  
  <pre><code>Took 2 dials
  </code></pre>
  
  <p>indicating that the call to <code>Get</code> only happened twice.</p>
  
  <p><strong>Specific question:</strong> Why are there only two calls to <code>Get</code> from rank 1?</p>
  
  <p><strong>More vague question:</strong> Am I making an obvious mistakes in this MWE? I am pretty new to mpi4py/MPI in general.</p>