How to/best practices to write a thread safe code? Also how to identify if a code is thread safe or not?
@Reckful Thanks for the links but these links merely explains what is processes, threads, synchronization between threads and some other concepts.
What I am interested in is a some sort of guidelines to be kept in mind while writing a program so that it is thread safe. By thread safe I mean when more than one thread executes the same function there shouldnt be any race condition or deadlock.
Hope you got my question.
I think 2 points to remember, at higher level:
- Are we dealing with any common data that is accessible among the threads, if so, how to maintain integrity of the data.
- Are we dealing with any common data structure that is accessible among threads, if so, how to serialize access to avoid any exceptions.
To give a better context, I heard this problem being asked in Adobe. So if an interviewer asks you this question then what would you tell?
First things first, concurrent programming is very different from parallel computing. Concurrent programming is a paradigm of software design and parallel computing deals with how processes are run in parallel.
"In programming, concurrency is the composition of independently executing processes, while parallelism is the simultaneous execution of (possibly related) computations. Concurrency is about dealing with lots of things at once. Parallelism is about doing lots of things at once" - Rob Pike
The bane of concurrent programming is shared mutability. Shared mutability of objects is the major reason for bottlenecks and slow code.
Here is a great talk that explains it very well
Your answer should be,
I will design in the application such that I will minimize shared mutability and try to give the example of the gopher burning books from the video above.
Sounds like they are wanting you to speak about mutex's and semaphores. Lot's of information on the internet about this and usually it'll lead into the question "ok, what's the difference between a mutex and binary semaphore?" (They behave the same outside of how/when/where the lock is set).
Synchronized of thread and process.
IPC: mutex, spinlock, socket, Semaphore, pipe, FIFO, message queue, share memory
@shuoy After that, they would ask you how to implement mutex or spinlock.....
This how I would approach this question.. I first start asking is it really necessary to make something a multithreaded application, because creating correct multithreaded application is hard even for experts.
I would suggest some design pattern which will effectively avoid dealing with threads.
- Keep you data/data structure immutable or make best effort to make it immutable.
- Since the advent of non-blocking-io, there is very few reason to create truly multi-threaded application. Employ pattern like GCD (Grand Central Dispatch), where various non-blocking-io completion events happen from a single thread
- Then finally suggest, that we can't always do this and multi-threaded is absolutely necessary in some cases and suggest various primitives we have to solve this problem.
stack overflow has a documentation about threading, it includes some basic concept and code samples of threading. I think it's helpful for beginners :)
I think we should consider the race condition part for multi-thread interaction.
So, think about synchronized methods, for example, mutex, spin lock, and some supported feature of programming languages.
Write multithreading code is hard. Debugging race conditions is even harder.
The best practice is not to write multi threaded code yourself at the beginning.
Think before you write code, try to write only stateless classes/modules/services for multi-threading and leverage those already existed, very mature stateful libraries/tools that guarantee thread-safe for the low level implementation.
but in some case, you still have to do it yourself...
- We should have a piece of code that will be called by more than one thread concurrently(say func())
- func() will make changes to global/shared variables
- to be safe means we should not have 'corrupted' results after concurrent calls from threadA and threadB, then we should adopt some synchronize/serialize techs such as mutex,semaphore.
- raise an example that is easy to identify thread safety:
threadA->func() ==> results in var1 = A and var2 = B, if run alone
threadB->func() ==> results in var1 = C and var2 = D, if run alone
if run concurrently, we should always get 'AB' or 'CD', never 'AD' or 'BC'.
Here I only thought about check thread safely from the results, but this implies that we should run tests until we find a 'bad' result, even a million of 'good' does not imply safely ;).
My two cents:
Probably, most important thing is to identify whether this is a situation where you need to consider thread safety.
Know the theory, but do reinvent the wheel if not necessary
If it turns out to be necessary to write thread safe code, consider what kind of library or primitive you could use in the programming language you are using. For example, in C++, folly https://github.com/facebook/folly/blob/master/folly/docs/Synchronized.md might be a good candidate to consider. In some situation, you may need to write some custome multithread libraries if this work could benefit other developers in your team.
Test the code carefully
Enjoyable discussions :)
Since we are coding at OS level, It would be reasonable to consider lock-free and (even better) wait-free data structures.
Those make sure about serializing reads/writes through memory barriers.
As a good post on lock-free queues, consult with the following link:
Great discussion guys ...
check this out for Java thread safe coding implementation :
I hope this will help you all guys :)
@Robin7 Not every scenario can be solved with lock free and sometimes it makes system performances degraded esp. with multiple consumer and producers.
Looks like your connection to LeetCode Discuss was lost, please wait while we try to reconnect.