What does lock actually do in multiprocessing?
up vote
0
down vote
favorite
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
|
show 1 more comment
up vote
0
down vote
favorite
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
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
|
show 1 more comment
up vote
0
down vote
favorite
up vote
0
down vote
favorite
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
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
python-multiprocessing
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
|
show 1 more comment
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
|
show 1 more comment
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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