How does threading.Lock actually work? (with multiple scenarios) - python-3.x

I have looked online and done some searching through stackoverflow and the internet about locks and I just seem to get a general understanding that when a lock is active another thread cannot use it??
I have multiple shared objects which are being read/written constantly throughout the script and I'm still not 100% sure how the locking function really works? When do you need to use it, when do you not need to use it and is it worth creating individual locks for each shared variable/object?
When a thread calls a lock does that mean other threads will only pause at that particular part of the script where the lock was originally called or does it somehow acknowledge to stop reading/writing any variables within the acquire/release function call throughout the entire script?
If I have multiple locks specifically for each shared variable/object and one lock function is called, does this effect the rest of the locks too?
I think to summerise, I'm struggling to understand the "in-depth" version of locking, only being able to find a general overview amongst previous explanations online.

Related

Multi-threading best practices

I have an application I've written in C#, although any similar language would apply here.
The application has the job of drawing a graphical scene to a window on a Form in real-time based on data it receives over various UDP and TCP sockets. Each UDP and TCP connection uses its own thread: these threads each modify various objects in memory which in turn modify the graphical display. I also have a user interface thread which is capable of receiving user events (button clicks, etc) which in turn modify those same objects and the display. Finally, I also have many timers that I fire which launch their own threads which modify those same objects and the display.
The objects in memory that are being modified consist of about 15 different classes.
Everything works pretty reliably, but with all of those different classes being modified by different threads, I've had to add a lot of synchronization locks. I've had to look at each class individually to determine which memory might be altered by more than one thread.
It seems very easy in this situation to miss one of those spots: to forget to add synchronization somewhere it's needed.
I'm curious as to whether others would implement this the way I did, or if there's some more elegant way: perhaps somehow putting all of the modification of class A on its own thread or something?
(P.S. I'm deathly afraid of asking a question here after things didn't go so well the first time. But I don't think my query here is super-obvious so I'm hoping you won't either. ;o)
I believe there is no straight-forward answer for this.
I have helped other to change the design to deal with similar situation. One of the most commonly used technique is to introduce a better abstraction.
For example, Assume that you have multiple thread that needs to update a Map containing Users, and another Set containing active user, instead of having locks for the User Map and Active User Set and have your threads acquire the locks manually, I'll suggest introducing an abstraction call UserRepository, in which contains the User map and Active User Set. UserRepository will provide some business-meaningful methods for other to manipulate the UserRepository. Locks are acquired in the methods of UserRepository, instead by the caller explicitly.
From my past experience, over 80% of complicated synchronization can be greatly simplified by having better design like the above mentioned example.
There are also other technique possible. For example, if the update is ok to do asynchronously, instead of having your threads update the resources directly, you may create command objects and put in a producer-consumer queue, and have a dedicate thread performing the update.
Also sometimes it is much easier to handle to have fewer locks. For example, when updating several resources, instead of having one lock for each resource, we can see the update as a whole action, and use only one lock for the coordination between threads. Of course it will increase contention, but there are cases that contention is not a big problem but we want maintainability instead.
I believe there are lots of other way to deal with similar situation, I am just sharing some of my previous experiences (which worked :P )

Write to file from many threads

i have a problem.
my progrem creates a some number of processes in the system (Windows).
They all must write some data in ONE file on a disk.
so, i need to synchronize them... but don't know...
exactly: my program calls SetWindowsHook and injects one dll in many processes. and they all need to write some data to one file
The synchronisation object that works across processes is a mutex.
Windows have a lock foreach file, so if one process is writting in a file windows wont let another write. Mutex is what you want, protect the code where you are writting into the file with one.
Single System As David mentioned, you can use a mutex to accomplish this task. In Windows, this is done by using named mutexes and (if you want) named semaphores to do this.
The function CreateMutex can be used to both create the mutex (by the first process) and open it by the other processes. Supply the same lpName value in all processes. Use WaitForSingleObject to gain ownership of the mutex. And use ReleaseMutex to give up ownership.
An example of creating a named mutex can be found here.
If use a named semaphore, you can accomplish the same thing by giving the semaphore an initial count of 1. Use CreateSemaphore to create and open it, WaitForSingleObject to gain ownership (same as with a mutex) and ReleaseSemaphore to give up ownwership.
Multiple Systems The above approach assumes that the processes are all running on the same system. If the processes are running on different systems, then you may need to use the idea mentioned by DVD. You can lock portions of a file and use that as the synchronization method. For example, you could, by convention, lock 1 byte at some offset (it can even be past the end of the file) as a type of semaphore. Using this mechanism, though, may mean you need to implement some kind of efficient wait depending on the functions you use. If you use CreateFile and LockFileEx, you can have the function do a blocked wait by not specifying LOCKFILE_FAIL_IMMEDIATELY in the call.
The answer to your problem is to implement Thread synchronization.
If you are using C#, you can put a lock{} statement over your file writing code.
For other languages, you must use a Monitor or Mutex class to synchronize.
Use Stream.Synchronized()
See http://msdn.microsoft.com/en-us/library/system.io.stream.synchronized.aspx. This method only works for C# though
I recently had to do almost this exact thing (for logging to a single file from a dll injected into multiple processes).
Use _fsopen() to open the file in each process and then use a mutex for synchronization to ensure that only one process at a time is ever writing to the file.

What does "readback" mean in terms of computer memory?

I am messing with multiple threads accessing a resource (probably memory). What does "readback" mean in this context?
Any guides will be helpful... Google didn't give me any good results.
I can think of several possible meanings for "readback". Here's the most likely; in a multithreaded environment, a lot can happen between your thread reading a value from memory and writing a changed value back to that memory. A simple yet effective way to detect changes is simply to get the value from memory again just before writing, and if it has changed from the value you started with, you know someone else changed it while you were working.
"Readback" may also refer to "repeatable reads", in which a locking mechanism is used to ensure that within the scope of an atomic set of operations, only the thread that obtained the lock on the resource can read OR write to it, ensuring that no other thread can change the value from what would be expected by the task if it ran single-threaded. That way, a thread doesn't have to detect external changes; the locking mechanism prevents such a thing from happening.
When I've encountered that term, it's usually in the context of writing a value to
a register or memory location that may also be accessed by some other software or
hardware. To check whether someone else has changed it, you might keep a private
copy of the data you wrote, and some time later read that shared register or memory location
to compare its current value to the stored private copy. That's the "readback".

Will this make the object thread-safe?

I have a native Visual C++ COM object and I need to make it completely thread-safe to be able to legally mark it as "free-threaded" in th system registry. Specifically I need to make sure that no more than one thread ever accesses any member variable of the object simultaneously.
The catch is I'm almost sure that no sane consumer of my COM object will ever try to simultaneously use the object from more than one thread. So I want the solution as simple as possible as long as it meets the requirement above.
Here's what I came up with. I add a mutex or critical section as a member variable of the object. Every COM-exposed method will acquire the mutex/section at the beginning and release before returning control.
I understand that this solution doesn't provide fine-grained access and this might slow execution down, but since I suppose simultaneous access will not really occur I don't care of this.
Will this solution suffice? Is there a simpler solution?
This solution should work, but I'd recommend mutexes over critical sections as they handle time-outs, which provide some level of fall back in case of deadlock. You also want to be very careful that a function locking a mutex does not call another function that has already locked the same mutex in the same thread. This shouldn't be a problem for your COM interface, so long as you don't add extra functionality on top of your mutex to the interface. You could hit issues if the COM includes call backs.
If you are certain that actual concurrent access is not going to happen in practice, then mutexing the entire execution is not an unreasonable approach.

_nolock CRT functions

I have recently discovered the existence of _nolock functions, and I am surprised by how little info I can find on these. It says it increases performance, but I can't find any benchmark. It also says they can be used in a multi-threaded program if the program does its own locking, but what has to be locked? Should all CRT calls go through the same lock? One per function? One per group of functions? If so, what defines groups?
Could you point me to some detailed information about these functions? Thanks :-)
You need to lock access to the file if you are accessing it from multiple threads. Otherwise, one thread could write right in the middle of another one. Try them out by printing to stdio to see the effects.
If you follow the links to the individual functions, you'll see the following line:
Use this function only in thread-safe
contexts such as single-threaded
applications or where the calling
scope already handles thread
isolation.
The only way to benchmark the performance difference would be to create a small program and test it out. As monjardin pointed out, you need to lock access to the file you're accessing with the function (unless, as noted in the documentation, you are in a single-threaded environment).

Resources