+ 2
Python Concurrency Problem (P#1)
Simulate a thread-safe counter that increments across 10 threads (each incrementing 1000 times). Ensure the final count is exactly 10,000 without race conditions. *Key Libraries: 'threading.Lock' or 'multiprocessing'.* https://sololearn.com/compiler-playground/cL7KhdUbSXOQ/?ref=app
20 Respuestas
+ 5
Jan
I've never really delved into Python's threading and multiprocessing before, too. So it's also a great learning opportunity for me.
Mihir Dev's code was a great starting point.
It looks like it could work, but it didn't, so that's interesting.
Shared objects is a major pain point in threading and multiprocessing, so I concentrated on that. and yes, the thread-safety warning light was flashing in my head when I first read the code. where's the locks?
+ 4
from
https://docs.python.org/3.6/library/multiprocessing.html#multiprocessing.Value
"Operations like += which involve a read and write are not atomic. So if, for instance, you want to atomically increment a shared value it is insufficient to just do
counter.value += 1
Assuming the associated lock is recursive (which it is by default) you can instead do
with counter.get_lock():
counter.value += 1
"
??? I get lost in cryptic documents too... what associated lock ?...
further reading gives:
"If lock is True (the default) then a new recursive lock object is created to synchronize access to the value. If lock is a Lock or RLock object then that will be used to synchronize access to the value. If lock is False then access to the returned object will not be automatically protected by a lock, so it will not necessarily be “process-safe”
so maybe a new lock object is created each time, unless you set lock to False or is using a global lock ...
+ 4
To simulate a thread-safe counter in Python and ensure the final count is exactly 10,000 without race conditions, we can use the threading module and specifically threading.Lock. Here's how to do it:
import threading
class ThreadSafeCounter:
def __init__(self):
self.count = 0
self.lock = threading.Lock() # Initialize a lock
def increment(self):
with self.lock: # Acquire the lock before incrementing
self.count += 1
# The lock is automatically released when exiting the 'with' block
def worker(counter, num_increments):
for _ in range(num_increments):
counter.increment()
if __name__ == "__main__":
counter = ThreadSafeCounter()
num_threads = 10
increments_per_thread = 1000
total_expected_count = num_threads * increments_per_thread
threads = []
for _ in range(num_threads):
thread = threading.Thread(target=worker, args=(counter, increments_per_thread))
threads.append(thread)
thread.start()
f
+ 2
Mihir Dev I think your approach should be something like this instead:
https://www.geeksforgeeks.org/multiprocessing-JUMP_LINK__&&__python__&&__JUMP_LINK-set-1/
+ 2
Bob_Li I think you used a little bit more time to research the problem than I did. I think I forgot that the thread-safe counter was the pivotal point in that task and not only about threads.
+ 2
Jan
there's never a need to solve a problem quickly for me. i like to think slowly. maybe that's why i avoid the code challenges.
it's even better if it's a problem that I can't solve. Then it means someone will be able to solve it and I learn something new, or I get to look up and try out new things.
with the push to remove the GIL in python, I hope Python's threading and multiprocessing capabilities will see new improvements.
+ 2
0mi patil
your answer is technically the correct one...
Mihir Dev was asking about multithreading, but his example was multiprocessing, not multithreading. I didn't notice that ... 😅
your solition is multithreading.👍
here's a comparison (I used Omi patil's code for the multithreading part) notice the process id and thread numbers :
https://sololearn.com/compiler-playground/chWUVUHYNGU8/?ref=app
+ 2
if you don't mind globals, here's a simpler way to share and lock objects in threads
https://sololearn.com/compiler-playground/cl56XE68Tca1/?ref=app
+ 1
this is not a homework writing service.
show your code where did you get stuck.
we are here and ready to help you
+ 1
Mihaly Nyilas my bad, I uploaded my code
+ 1
I made a little test of your code, and it seems that your counter is resetting to 0 every time the Process is called.
+ 1
Jan thanks this makes sense now
+ 1
Hey Bob_Li, this is what I needed. Thanks for the crystal-clear solution! 🙌
Quick question about 'get_lock()': Does it create a new lock each time it’s called, or is it reusing the same lock object under the hood? (Just curious how lightweight it is compared to a manual 'Lock()'.)
Again, massive props for the help!
+ 1
Bob_Li Normally, when I see a users problem, I say to myself - can I solve this within minutes with a quick solution! But then it happens I either misunderstand the users problem, or I have to realize that it's going to take more time to research than I expected. Oh no, I'm on a mobile with a complicated problem. That's not good, because I cannot use hours on that now, especially if I have do dive into something that I normally don't deal with.
+ 1
Solution received?
+ 1
Mihir Dev ok
0
Jan How should I resolve it or what should be my approach to solve it?
0
.
0
Hariharan S Yes already