What "thread safe" really means...In Practical terms What "thread safe" really means...In Practical terms multithreading multithreading

What "thread safe" really means...In Practical terms


A precise technical definition that everyone agrees on is difficult to come up with.

Informally, "thread safe" simply means "is reasonably well-behaved when called from multiple threads". The object will not crash or produce crazy results when called from multiple threads.

The question you actually need to get answered if you intend to do multi-threaded programming involving a particular object is "what is the threading model expected by the object?"

There are a bunch of different threading models. For example, the "free threaded" model is "do whatever you want from any thread; the object will deal with it." That's the easiest model for you to deal with, and the hardest for the object provider to provide.

On the other end of the spectrum is the "single threaded" model -- all instances of all objects must be accessed from a single thread, period.

And then there's a bunch of stuff in the middle. The "apartment threaded" model is "you can create two instances on two different threads, but whatever thread you use to create an instance is the thread you must always use to call methods on that instance".

The "rental threaded" model is "you can call one instance on two different threads, but you are responsible for ensuring that no two threads are ever doing so at the same time".

And so on. Find out what the threading model your object expects before you attempt to write threading code against it.


Given that a Collection, for instance, is not threasafe:

var myDic = new Dictionary<string, string>();

In a multhread environment, this will throw:

string s = null;if (!myDic.TryGetValue("keyName", out s)) {    s = new string('#', 10);    myDic.Add("keyName", s);}

As one thread is working trying to add the KeyValuePair to the dictionary myDic, another one may TryGetValue(). As Collections can't be read and written at the same time, an Exception will occur.

However, on the other hand, if you try this:

// Other threads will wait here until the variable myDic gets unlocked from the preceding thread that has locked it.lock (myDic) {    string s = null;    if (!myDic.TryGetValue("keyName", out s)) {        s = new string('#', 10);        myDic.Add("keyName", s);    }} // The first thread that locked the myDic variable will now release the lock so that other threads will be able to work with the variable.

Then suddenly, the second thread trying to get the same "keyName" key value will not have to add it to the dictionary as the first thread already added it.

So in short, threadsafe means that an object supports being used by multiple threads at the same time, or will lock the threads appropriately for you, without you having to worry about threadsafety.

2. I don't think GhostScript is now threadsafe. It is majorly using multiple threads to perform its tasks, so this makes it deliver a greater performance, that's all.

3. Depending on your budget and your requirements, it may be worthy. But if you build around wrapper, you could perhaps only lock() where it is convenient to do so, or if you do not use multithreading yourself, it is definitely not worth to pay for threadsafety. This means only that if YOUR application uses multithreading, then you will not suffer the consequences of a library not being threadsafe. Unless you really multihread, it is not worth paying for a threadsafe library.


I am a Ghostscript developer, and won't repeat the general theory about thread safety.
We have been working on getting GS to be thread safe so that multiple 'instances' can be created using gsapi_new_instance from within a single process, but we have not yet completed this to our satisfaction (which includes our QA testing of this).
The graphics library is, however, thread safe and the multi-threaded rendering relies on this to allow us to spawn multiple threads to render bands from a display list in parallel. The multi-threaded rendering has been subjected to a lot of QA testing and is used by many commercial licensees to improve performance on multi-core CPU's.

You can bet we will announce when we finally support multiple instances of GS. Most people that want to use current GS from applications that need multiple instances spawn separate processes for each instance so that GS doesn't need to be thread safe. The GS can run a job as determined by the argument list options or I/O can be piped to/from the process to provide data and collect output.