What does lock actually do in multiprocessing?











up vote
0
down vote

favorite
2












I trying to learn parallel programming and multiprocessing in python. I know that lock is like "sleep" so it make the other process waits until the current process finish that chunk of code or shared memory. But the problem is that the output is



import multiprocessing 
# function to withdraw from account
def withdraw(balance, lock):
for _ in range(10):
lock.acquire()
print("with")
balance.value = balance.value - 1
lock.release()
# function to deposit to account
def deposit(balance, lock):
for _ in range(10):
lock.acquire()
print("depp")
balance.value = balance.value + 1
lock.release()

def perform_transactions():
# initial balance (in shared memory)
balance = multiprocessing.Value('i', 100)
# creating a lock object
lock = multiprocessing.Lock()
# creating new processes
p1 = multiprocessing.Process(target=withdraw, args=(balance,lock))
p2 = multiprocessing.Process(target=deposit, args=(balance,lock))
# starting processes
p1.start()
p2.start()
# wait until processes are finished
p1.join()
p2.join()
# print final balance
print("Final balance = {}".format(balance.value))
if __name__ == "__main__":
for _ in range(10):
# perform same transaction process 10 times
perform_transactions()


first output:



with
with
with
with
with
with
with
with
with
with
depp
depp
depp
depp
depp
depp
depp
depp
depp
depp
Final balance = 100



I thought that it would be something like "dep with dep with ...etc" but it prints dep ten times and with 10 times which means it performed an entire process first with no parallelism.
It would make sense if the "lock.acquire()" was before the loop and "lock.release()" was after the loop.

Another output which is weird too



with
with
with
depp
depp
depp
depp
depp
depp
depp
depp
depp
depp
with
with
with
with
with
with
with
Final balance = 100









share|improve this question


















  • 1




    Releasing the lock won't cause the other thread to pick it up immediately unless it is already in the queue for that lock. Since you are only running through the loop 10x, it is quite possible that the first task is able to complete before the second task can even start. Try adding some delay in the loops (time.sleep(x)) or else increase the # of iterations. Also, add a printout indicating when each task starts and ends to help you visualize..
    – Ryan Pierce Williams
    Nov 10 at 23:16












  • @RyanPierceWilliams yes yes thank you. I added (time.sleep(x)) and now it's working as expected. But it's still weird to me. because How on earth does an entire process finish before even the other one starts? another thing please, you said "Releasing the lock won't cause the other thread to pick it up immediately." But Is't the most reasonable thing to do is that when process one releases the lock, the other process will be standing in the queue waiting the lock to get released and when process two acquire it, process one will stand in the queue...etc
    – floyd
    Nov 10 at 23:30






  • 1




    Note that you call p1.start(); prior to p2.start(); Thus p1 has started before you have even attempted to start p2. If you want to make sure both threads have started before either executes, have your main thread acquire the lock and only release after p2.start();
    – Ryan Pierce Williams
    Nov 10 at 23:41












  • you mean like that > lock.acquire(); p1.start(); p2.start(); lock.release()
    – floyd
    Nov 10 at 23:47






  • 1




    There's nothing wrong with your output. The order that asynchronous operations will complete in is unpredictable unless you force them to synchronize. If you always want to withdraw -> deposit -> withdraw -> deposit -> ... then you need to synchronize these actions. For instance: instead of having two threads, have one thread that calls withdraw -> deposit in a loop.
    – Ryan Pierce Williams
    Nov 10 at 23:58















up vote
0
down vote

favorite
2












I trying to learn parallel programming and multiprocessing in python. I know that lock is like "sleep" so it make the other process waits until the current process finish that chunk of code or shared memory. But the problem is that the output is



import multiprocessing 
# function to withdraw from account
def withdraw(balance, lock):
for _ in range(10):
lock.acquire()
print("with")
balance.value = balance.value - 1
lock.release()
# function to deposit to account
def deposit(balance, lock):
for _ in range(10):
lock.acquire()
print("depp")
balance.value = balance.value + 1
lock.release()

def perform_transactions():
# initial balance (in shared memory)
balance = multiprocessing.Value('i', 100)
# creating a lock object
lock = multiprocessing.Lock()
# creating new processes
p1 = multiprocessing.Process(target=withdraw, args=(balance,lock))
p2 = multiprocessing.Process(target=deposit, args=(balance,lock))
# starting processes
p1.start()
p2.start()
# wait until processes are finished
p1.join()
p2.join()
# print final balance
print("Final balance = {}".format(balance.value))
if __name__ == "__main__":
for _ in range(10):
# perform same transaction process 10 times
perform_transactions()


first output:



with
with
with
with
with
with
with
with
with
with
depp
depp
depp
depp
depp
depp
depp
depp
depp
depp
Final balance = 100



I thought that it would be something like "dep with dep with ...etc" but it prints dep ten times and with 10 times which means it performed an entire process first with no parallelism.
It would make sense if the "lock.acquire()" was before the loop and "lock.release()" was after the loop.

Another output which is weird too



with
with
with
depp
depp
depp
depp
depp
depp
depp
depp
depp
depp
with
with
with
with
with
with
with
Final balance = 100









share|improve this question


















  • 1




    Releasing the lock won't cause the other thread to pick it up immediately unless it is already in the queue for that lock. Since you are only running through the loop 10x, it is quite possible that the first task is able to complete before the second task can even start. Try adding some delay in the loops (time.sleep(x)) or else increase the # of iterations. Also, add a printout indicating when each task starts and ends to help you visualize..
    – Ryan Pierce Williams
    Nov 10 at 23:16












  • @RyanPierceWilliams yes yes thank you. I added (time.sleep(x)) and now it's working as expected. But it's still weird to me. because How on earth does an entire process finish before even the other one starts? another thing please, you said "Releasing the lock won't cause the other thread to pick it up immediately." But Is't the most reasonable thing to do is that when process one releases the lock, the other process will be standing in the queue waiting the lock to get released and when process two acquire it, process one will stand in the queue...etc
    – floyd
    Nov 10 at 23:30






  • 1




    Note that you call p1.start(); prior to p2.start(); Thus p1 has started before you have even attempted to start p2. If you want to make sure both threads have started before either executes, have your main thread acquire the lock and only release after p2.start();
    – Ryan Pierce Williams
    Nov 10 at 23:41












  • you mean like that > lock.acquire(); p1.start(); p2.start(); lock.release()
    – floyd
    Nov 10 at 23:47






  • 1




    There's nothing wrong with your output. The order that asynchronous operations will complete in is unpredictable unless you force them to synchronize. If you always want to withdraw -> deposit -> withdraw -> deposit -> ... then you need to synchronize these actions. For instance: instead of having two threads, have one thread that calls withdraw -> deposit in a loop.
    – Ryan Pierce Williams
    Nov 10 at 23:58













up vote
0
down vote

favorite
2









up vote
0
down vote

favorite
2






2





I trying to learn parallel programming and multiprocessing in python. I know that lock is like "sleep" so it make the other process waits until the current process finish that chunk of code or shared memory. But the problem is that the output is



import multiprocessing 
# function to withdraw from account
def withdraw(balance, lock):
for _ in range(10):
lock.acquire()
print("with")
balance.value = balance.value - 1
lock.release()
# function to deposit to account
def deposit(balance, lock):
for _ in range(10):
lock.acquire()
print("depp")
balance.value = balance.value + 1
lock.release()

def perform_transactions():
# initial balance (in shared memory)
balance = multiprocessing.Value('i', 100)
# creating a lock object
lock = multiprocessing.Lock()
# creating new processes
p1 = multiprocessing.Process(target=withdraw, args=(balance,lock))
p2 = multiprocessing.Process(target=deposit, args=(balance,lock))
# starting processes
p1.start()
p2.start()
# wait until processes are finished
p1.join()
p2.join()
# print final balance
print("Final balance = {}".format(balance.value))
if __name__ == "__main__":
for _ in range(10):
# perform same transaction process 10 times
perform_transactions()


first output:



with
with
with
with
with
with
with
with
with
with
depp
depp
depp
depp
depp
depp
depp
depp
depp
depp
Final balance = 100



I thought that it would be something like "dep with dep with ...etc" but it prints dep ten times and with 10 times which means it performed an entire process first with no parallelism.
It would make sense if the "lock.acquire()" was before the loop and "lock.release()" was after the loop.

Another output which is weird too



with
with
with
depp
depp
depp
depp
depp
depp
depp
depp
depp
depp
with
with
with
with
with
with
with
Final balance = 100









share|improve this question













I trying to learn parallel programming and multiprocessing in python. I know that lock is like "sleep" so it make the other process waits until the current process finish that chunk of code or shared memory. But the problem is that the output is



import multiprocessing 
# function to withdraw from account
def withdraw(balance, lock):
for _ in range(10):
lock.acquire()
print("with")
balance.value = balance.value - 1
lock.release()
# function to deposit to account
def deposit(balance, lock):
for _ in range(10):
lock.acquire()
print("depp")
balance.value = balance.value + 1
lock.release()

def perform_transactions():
# initial balance (in shared memory)
balance = multiprocessing.Value('i', 100)
# creating a lock object
lock = multiprocessing.Lock()
# creating new processes
p1 = multiprocessing.Process(target=withdraw, args=(balance,lock))
p2 = multiprocessing.Process(target=deposit, args=(balance,lock))
# starting processes
p1.start()
p2.start()
# wait until processes are finished
p1.join()
p2.join()
# print final balance
print("Final balance = {}".format(balance.value))
if __name__ == "__main__":
for _ in range(10):
# perform same transaction process 10 times
perform_transactions()


first output:



with
with
with
with
with
with
with
with
with
with
depp
depp
depp
depp
depp
depp
depp
depp
depp
depp
Final balance = 100



I thought that it would be something like "dep with dep with ...etc" but it prints dep ten times and with 10 times which means it performed an entire process first with no parallelism.
It would make sense if the "lock.acquire()" was before the loop and "lock.release()" was after the loop.

Another output which is weird too



with
with
with
depp
depp
depp
depp
depp
depp
depp
depp
depp
depp
with
with
with
with
with
with
with
Final balance = 100






python-multiprocessing






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 23:06









floyd

18410




18410








  • 1




    Releasing the lock won't cause the other thread to pick it up immediately unless it is already in the queue for that lock. Since you are only running through the loop 10x, it is quite possible that the first task is able to complete before the second task can even start. Try adding some delay in the loops (time.sleep(x)) or else increase the # of iterations. Also, add a printout indicating when each task starts and ends to help you visualize..
    – Ryan Pierce Williams
    Nov 10 at 23:16












  • @RyanPierceWilliams yes yes thank you. I added (time.sleep(x)) and now it's working as expected. But it's still weird to me. because How on earth does an entire process finish before even the other one starts? another thing please, you said "Releasing the lock won't cause the other thread to pick it up immediately." But Is't the most reasonable thing to do is that when process one releases the lock, the other process will be standing in the queue waiting the lock to get released and when process two acquire it, process one will stand in the queue...etc
    – floyd
    Nov 10 at 23:30






  • 1




    Note that you call p1.start(); prior to p2.start(); Thus p1 has started before you have even attempted to start p2. If you want to make sure both threads have started before either executes, have your main thread acquire the lock and only release after p2.start();
    – Ryan Pierce Williams
    Nov 10 at 23:41












  • you mean like that > lock.acquire(); p1.start(); p2.start(); lock.release()
    – floyd
    Nov 10 at 23:47






  • 1




    There's nothing wrong with your output. The order that asynchronous operations will complete in is unpredictable unless you force them to synchronize. If you always want to withdraw -> deposit -> withdraw -> deposit -> ... then you need to synchronize these actions. For instance: instead of having two threads, have one thread that calls withdraw -> deposit in a loop.
    – Ryan Pierce Williams
    Nov 10 at 23:58














  • 1




    Releasing the lock won't cause the other thread to pick it up immediately unless it is already in the queue for that lock. Since you are only running through the loop 10x, it is quite possible that the first task is able to complete before the second task can even start. Try adding some delay in the loops (time.sleep(x)) or else increase the # of iterations. Also, add a printout indicating when each task starts and ends to help you visualize..
    – Ryan Pierce Williams
    Nov 10 at 23:16












  • @RyanPierceWilliams yes yes thank you. I added (time.sleep(x)) and now it's working as expected. But it's still weird to me. because How on earth does an entire process finish before even the other one starts? another thing please, you said "Releasing the lock won't cause the other thread to pick it up immediately." But Is't the most reasonable thing to do is that when process one releases the lock, the other process will be standing in the queue waiting the lock to get released and when process two acquire it, process one will stand in the queue...etc
    – floyd
    Nov 10 at 23:30






  • 1




    Note that you call p1.start(); prior to p2.start(); Thus p1 has started before you have even attempted to start p2. If you want to make sure both threads have started before either executes, have your main thread acquire the lock and only release after p2.start();
    – Ryan Pierce Williams
    Nov 10 at 23:41












  • you mean like that > lock.acquire(); p1.start(); p2.start(); lock.release()
    – floyd
    Nov 10 at 23:47






  • 1




    There's nothing wrong with your output. The order that asynchronous operations will complete in is unpredictable unless you force them to synchronize. If you always want to withdraw -> deposit -> withdraw -> deposit -> ... then you need to synchronize these actions. For instance: instead of having two threads, have one thread that calls withdraw -> deposit in a loop.
    – Ryan Pierce Williams
    Nov 10 at 23:58








1




1




Releasing the lock won't cause the other thread to pick it up immediately unless it is already in the queue for that lock. Since you are only running through the loop 10x, it is quite possible that the first task is able to complete before the second task can even start. Try adding some delay in the loops (time.sleep(x)) or else increase the # of iterations. Also, add a printout indicating when each task starts and ends to help you visualize..
– Ryan Pierce Williams
Nov 10 at 23:16






Releasing the lock won't cause the other thread to pick it up immediately unless it is already in the queue for that lock. Since you are only running through the loop 10x, it is quite possible that the first task is able to complete before the second task can even start. Try adding some delay in the loops (time.sleep(x)) or else increase the # of iterations. Also, add a printout indicating when each task starts and ends to help you visualize..
– Ryan Pierce Williams
Nov 10 at 23:16














@RyanPierceWilliams yes yes thank you. I added (time.sleep(x)) and now it's working as expected. But it's still weird to me. because How on earth does an entire process finish before even the other one starts? another thing please, you said "Releasing the lock won't cause the other thread to pick it up immediately." But Is't the most reasonable thing to do is that when process one releases the lock, the other process will be standing in the queue waiting the lock to get released and when process two acquire it, process one will stand in the queue...etc
– floyd
Nov 10 at 23:30




@RyanPierceWilliams yes yes thank you. I added (time.sleep(x)) and now it's working as expected. But it's still weird to me. because How on earth does an entire process finish before even the other one starts? another thing please, you said "Releasing the lock won't cause the other thread to pick it up immediately." But Is't the most reasonable thing to do is that when process one releases the lock, the other process will be standing in the queue waiting the lock to get released and when process two acquire it, process one will stand in the queue...etc
– floyd
Nov 10 at 23:30




1




1




Note that you call p1.start(); prior to p2.start(); Thus p1 has started before you have even attempted to start p2. If you want to make sure both threads have started before either executes, have your main thread acquire the lock and only release after p2.start();
– Ryan Pierce Williams
Nov 10 at 23:41






Note that you call p1.start(); prior to p2.start(); Thus p1 has started before you have even attempted to start p2. If you want to make sure both threads have started before either executes, have your main thread acquire the lock and only release after p2.start();
– Ryan Pierce Williams
Nov 10 at 23:41














you mean like that > lock.acquire(); p1.start(); p2.start(); lock.release()
– floyd
Nov 10 at 23:47




you mean like that > lock.acquire(); p1.start(); p2.start(); lock.release()
– floyd
Nov 10 at 23:47




1




1




There's nothing wrong with your output. The order that asynchronous operations will complete in is unpredictable unless you force them to synchronize. If you always want to withdraw -> deposit -> withdraw -> deposit -> ... then you need to synchronize these actions. For instance: instead of having two threads, have one thread that calls withdraw -> deposit in a loop.
– Ryan Pierce Williams
Nov 10 at 23:58




There's nothing wrong with your output. The order that asynchronous operations will complete in is unpredictable unless you force them to synchronize. If you always want to withdraw -> deposit -> withdraw -> deposit -> ... then you need to synchronize these actions. For instance: instead of having two threads, have one thread that calls withdraw -> deposit in a loop.
– Ryan Pierce Williams
Nov 10 at 23:58

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244296%2fwhat-does-lock-actually-do-in-multiprocessing%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244296%2fwhat-does-lock-actually-do-in-multiprocessing%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Coverage of Google Street View

Full-time equivalent

Surfing