Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

When creating a library for a simple program, is it more cost effective to make it thread safe or is there a way to detect the program's use in a multithreaded program and ASSERT() or otherwise determine (preferably at compile or link time) that it may create problems.

Related help for this question would be automated tool support for finding potential problems with thread safety, programming language features that enforce it,

share|improve this question
3  
Cost effective, simple, and thread safe. Hmmm. Quoting from Sesame Street, One of these things does not go with the others. One of these things doesn't belong. –  David Hammen Sep 14 '12 at 16:43
1  
So I guess this is a vote for warning people using the library. –  DeveloperDon Sep 14 '12 at 16:50
add comment

3 Answers

up vote 2 down vote accepted

It depends on the cost to make it thread safe (in terms of development time and effort). Things to consider include:

  • Making a library thread safe can be challenging, particularly when dealing with lower level thread primitives, such as Java's synchronized and C#'s lock keywords, when efficiency or speed is critical.
  • Some environments provide higher level abstractions like C# 4.5's await and async keywords. Use them if available.
  • Use thread-safe library classes, like those in .Net's System.Collections.Concurrent namespace.
  • Thread safety may impact the code's portability. For example, C code using pthread mutexes will not work on Windows without additional library support.

It also depends on how likely the library will be used in a multi-threaded environment and the conventions for the language used. For example, Microsoft original class library design guidelines stated that non-static members need not be thread safe.

Either way, the best approach is to clearly document what is and what is not thread safe.

share|improve this answer
add comment

So I guess this is a vote for warning people using the library.

Yes, that is exactly what my snarky comment was. Unless there is a good reason for adding that expense, don't do it. Thread safety is expensive, to the designer, to the developer, to the tester, and also to the user who doesn't need it. You are guilty of premature optimization unless there is a very good reason to absorb that expense.

  • Good reason: You are a developer working on a logging library where a single logged item might comprise many lines in the log file, and the logger might be called from multiple threads. The need for thread safety is right there in the requirements, and those requirements make sense.
  • Bad reason: After doing so well on the logging library, you are made the project lead that amongst other things will develop a random number library. Here the driving requirements are numerical correctness, ease of use, and speed. You, the project lead, decide to add thread safety to the requirements just because ensuring thread safety was so much fun in the logging library project. You've just blown away my need for speed. I might make trillions of calls to the PRNG during an overnight Monte Carlo run. Your library is about as useful to me as is the built-in rand() function.

You build in thread safety because it makes sense and because there is a need for it, and even then you need to be judicious about how you proceed.

share|improve this answer
add comment

Something like this (C#) MIGHT do the trick...

public class MyNonThreadSafeClass()
{
   public MyNonThreadSafeClass()
   {
       currentThreadId = Thread.CurrentThread.ManagedThreadId;
   }

   private readonly int currentThreadId;

   public void SomeNonThreadSafeMethod()
   {
      AssertSameThread();

      //do your thing   
   }

   private void AssertSameThread()
   {
      if(currentThreadId != Thread.CurrentThread.ManagedThreadId)
         throw new InvalidOperationException("Method must be called on the same thread that created the containing object");
   }
}

This would ensure that only the thread that created the object instance could work with it. Variations of this could ensure that no one method is called concurrently by different threads at the same time (but allow one thread to create the instance and then give it to another thread to work with), or that the creating thread must have a message pump (and is thus a UI thread and so very likely to be the app's "main" thread).

However, overall, if you expect your library to be used by parallel threads of a process, and want to support that, I would make it thread-safe. It's not really that hard; use monitors, mutexes or other locks to protect shared state, and favor "pure functions" that don't rely on instance-scoped state.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.