Tutorial :When is multi-threading not a good idea? [closed]



Question:

I was recently working on an application that sent and received messages over Ethernet and Serial. I was then tasked to add the monitoring of DIO discretes. I throught,

"No reason to interrupt the main thread which is involved in message processing, I'll just create another thread that monitors DIO."

This decision, however, proved to be poor. Sometimes the main thread would be interrupted between a Send and a Receive serial message. This interruption would disrupt the timing and alas, messages would be lost (forever).

I found another way to monitor the DIO without using another thread and Ethernet and Serial communication were restored to their correct functionality.

The whole fiasco, however, got me thinking. Are their any general guidelines about when not to use multiple-threads and/or does anyone have anymore examples of situations when using multiple-threads is not a good idea?

**EDIT:Based on your comments and after scowering the internet for information, I have composed a blog post entitled When is multi-threading not a good idea?


Solution:1

  1. On a single processor machine and a desktop application, you use multi threads so you don't freeze the app but for nothing else really.
  2. On a single processor server and a web based app, no need for multi threading because the web server handles most of it.
  3. On a multi-processor machine and desktop app, you are suggested to use multi threads and parallel programming. Make as many threads as there are processors.
  4. On a multi-processor server and a web based app, no need again for multi threads because the web server handles it.

In total, if you use multiple threads for other than un-freezing desktop apps and any other generic answer, you will make the app slower if you have a single core machine due to the threads interrupting each other.

Why? Because of the hardware switches. It takes time for the hardware to switch between threads in total. On a multi-core box, go ahead and use 1 thread for each core and you will greatly see a ramp up.


Solution:2

To paraphrase an old quote: A programmer had a problem. He thought, "I know, I'll use threads." Now the programmer has two problems. (Often attributed to JWZ, but it seems to predate his use of it talking about regexes.)

A good rule of thumb is "Don't use threads, unless there's a very compelling reason to use threads." Multiple threads are asking for trouble. Try to find a good way to solve the problem without using multiple threads, and only fall back to using threads if avoiding it is as much trouble as the extra effort to use threads. Also, consider switching to multiple threads if you're running on a multi-core/multi-CPU machine, and performance testing of the single threaded version shows that you need the performance of the extra cores.


Solution:3

Multi-threading is a bad idea if:

  • Several threads access and update the same resource (set a variable, write to a file), and you don't understand thread safety.

  • Several threads interact with each other and you don't understand mutexes and similar thread-management tools.

  • Your program uses static variables (threads typically share them by default).

  • You haven't debugged concurrency issues.


Solution:4

Actually, multi threading is not scalable and is hard to debug, so it should not be used in any case if you can avoid it. There is few cases where it is mandatory : when performance on a multi CPU matters, or when you deal whith a server that have a lot of clients taking a long time to answer.

In any other cases, you can use alternatives such as queue + cron jobs or else.


Solution:5

You might want to take a look at the Dan Kegel's "The C10K problem" web page about handling multiple data sources/sinks.

Basically it is best to use minimal threads, which in sockets can be done in most OS's w/ some event system (or asynchronously in Windows using IOCP).

When you run into the case where the OS and/or libraries do not offer a way to perform communication in a non-blocking manner, it is best to use a thread-pool to handle them while reporting back to the same event loop.

Example diagram of layout:

Per CPU [*] EVENTLOOP   ------ Handles nonblocking I/O using OS/library utilities                         |                        \___  Threadpool for various blocking events                         Threadpool for handling the I/O messages that would take long  


Solution:6

Multi-threading is not a good idea if you need to guarantee precise physical timing (like in your example). Other cons include intensive data exchange between threads. I would say multi-threading is good for really parallel tasks if you don't care much about their relative speed/priority/timing.


Solution:7

A recent application I wrote that had to use multithreading (although not unbounded number of threads) was one where I had to communicate in several directions over two protocols, plus monitoring a third resource for changes. Both protocol libraries required a thread to run the respective event loop in, and when those were accounted for, it was easy to create a third loop for the resource monitoring. In addition to the event loop requirements, the messages going through the wires had strict timing requirements, and one loop couldn't be risked blocking the other, something that was further alleviated by using a multicore CPU (SPARC).

There were further discussions on whether each message processing should be considered a job that was given to a thread from a thread pool, but in the end that was an extension that wasn't worth the work.

All-in-all, threads should if possible only be considered when you can partition the work into well defined jobs (or series of jobs) such that the semantics are relatively easy to document and implement, and you can put an upper bound on the number of threads you use and that need to interact. Systems where this is best applied are almost message passing systems.


Solution:8

Multithreading is bad except in the single case where it is good. This case is

  1. The work is CPU Bound, or parts of it is CPU Bound
  2. The work is parallelisable.

If either or both of these conditions are missing, multithreading is not going to be a winning strategy.

If the work is not CPU bound, then you are waiting not on threads to finish work, but rather for some external event, such as network activity, for the process to complete its work. Using threads, there is the additional cost of context switches between threads, The cost of synchronization (mutexes, etc), and the irregularity of thread preemption. The alternative in most common use is asynchronous IO, in which a single thread listens to several io ports, and acts on whichever happens to be ready now, one at a time. If by some chance these slow channels all happen to become ready at the same time, It might seem like you will experience a slow-down, but in practice this is rarely true. The cost of handling each port individually is often comparable or better than the cost of synchronizing state on multiple threads as each channel is emptied.

Many tasks may be compute bound, but still not practical to use a multithreaded approach because the process must synchronise on the entire state. Such a program cannot benefit from multithreading because no work can be performed concurrently. Fortunately, most programs that require enormous amounts of CPU can be parallelized to some level.


Solution:9

In priciple everytime there is no overhead for the caller to wait in a queue.


Solution:10

A couple more possible reasons to use threads:

  1. Your platform lacks asynchronous I/O operations, e.g. Windows ME (No completion ports or overlapped I/O, a pain when porting XP applications that use them.) Java 1.3 and earlier.
  2. A third-party library function that can hang, e.g. if a remote server is down, and the library provides no way to cancel the operation and you can't modify it.

Keeping a GUI responsive during intensive processing doesn't always require additional threads. A single callback function is usually sufficient.

If none of the above apply and I still want parallelism for some reason, I prefer to launch an independent process if possible.


Solution:11

I would say multi-threading is generally used to:

  1. Allow data processing in the background while a GUI remains responsive
  2. Split very big data analysis onto multiple processing units so that you can get your results quicker.
  3. When you're receiving data from some hardware and need something to continuously add it to a buffer while some other element decides what to do with it (write to disk, display on a GUI etc.).

So if you're not solving one of those issues, it's unlikely that adding threads will make your life easier. In fact it'll almost certainly make it harder because as others have mentioned; debugging mutithreaded applications is considerably more work than a single threaded solution.

Security might be a reason to avoid using multiple threads (over multiple processes). See Google chrome for an example of multi-process safety features.


Solution:12

Multi-threading is scalable, and will allow your UI to maintain its responsivness while doing very complicated things in the background. I don't understand where other responses are acquiring their information on multi-threading.

When you shouldn't multi-thread is a mis-leading question to your problem. Your problem is this: Why did multi-threading my application cause serial / ethernet communications to fail?

The answer to that question will depend on the implementation, which should be discussed in another question. I know for a fact that you can have both ethernet and serial communications happening in a multi-threaded application at the same time as numerous other tasks without causing any data loss.

The one reason to not use multi-threading is:

  1. There is one task, and no user interface with which the task will interfere.

The reasons to use mutli-threading are:

  1. Provides superior responsiveness to the user
  2. Performs multiple tasks at the same time to decrease overall execution time
  3. Uses more of the current multi-core CPUs, and multi-multi-cores of the future.

There are three basic methods of multi-threaded programming that make thread safety implemented with ease - you only need to use one for success:

  1. Thread Safe Data types passed between threads.
  2. Thread Safe Methods in the threaded object to modify data passed between.
  3. PostMessage capabilities to communicate between threads.


Solution:13

Are the processes parallel? Is performance a real concern? Are there multiple 'threads' of execution like on a web server? I don't think there is a finite answer.


Solution:14

A common source of threading issues is the usual approaches employed to synchronize data. Having threads share state and then implement locking at all the appropriate places is a major source of complexity for both design and debugging. Getting the locking right to balance stability, performance, and scalability is always a hard problem to solve. Even the most experienced experts get it wrong frequently. Alternative techniques to deal with threading can alleviate much of this complexity. The Clojure programming language implements several interesting techniques for dealing with concurrency.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »