multiprocessing.sharedctypes and built-in locks

Aaron Brady castironpi at gmail.com
Sat Mar 14 22:19:07 CET 2009


On Mar 14, 7:11 am, Ahmad Syukri bin Abdollah <syoc... at gmail.com>
wrote:
> I'm trying this on Python 3.0.1
> Consider the following code:
> """
> import multiprocessing as mp
>
> def jambu(b,i,gl):
>     for n in range(100000):
>        with gl[i]:
>             b[i]+=2
>        with gl[3-i]:
>             b[3-i]-=1
>
> def main():
>     b = mp.RawArray('i',4)
>     gl = []
>     proc = []
>     for i in range(len(b)):
>         gl.append(mp.Lock())
>         proc.append(mp.Process(target=jambu,args=(b,i,gl)))
>     for p in proc:
>         p.start()
>     for p in proc:
>         p.join()
>     print(b[:])
>     print(sum(b[:]))
> main()
> """
> (Yes, I'm aware that I didn't pass the lock array as shared variable,
> but since they're not reassigned, it should be okay) The above code
> should produce an output like this:
>   [100000, 100000, 100000, 100000]
>   400000
> Now, in the documentation for multiprocessing module, it says that
> multiprocessing.Array will automatically create a lock to ensure
> process-safe synchronization. So I suppose the above code can be
> simplified as follows:
> """
> import multiprocessing as mp
>
> def jambu(b,i):
>     for n in range(100000):
>         b[i]+=2
>         b[3-i]-=1
>
> def main():
>     b = mp.Array('i',4)
>     proc = []
>     for i in range(len(b)):
>         gl.append(mp.Lock())
>         proc.append(mp.Process(target=jambu,args=(b,i)))
>     for p in proc:
>         p.start()
>     for p in proc:
>         p.join()
>     print(b[:])
>     print(sum(b[:]))
> main()
> """
> The output of this second code isn't consistent with the first one,
> implying multiprocessing.Array (or even multiprocessing.Value; I've
> also tried with this one) isn't as atomic as I understand it should
> be. So what is the actual meaning of having "a Lock object which will
> be used to synchronize access to the value"? Is it only for getting,
> and not for assigning values?
>
> Regards,
> Ahmad Syukri

Your code hung on my machine.  The call to 'main()' should be in an
'if __name__' block:

if __name__== '__main__':
    main()

Is it possible you are just seeing the effects of the non-atomic
'__iadd__' operation?  That is, the value is read, added, and written
at different times, between which other processes might have
intervened.



More information about the Python-list mailing list