views:

330

answers:

9

I'd like to start learning multithreading in C++. I'm learning it in Java as well. In Java, if I write a program which uses multithreading, it will work anywhere. However in C++, doesn't multithreading rely on platform-specific API's? If so, that would seem to get in the way of portability.

How can I do multithreading in C++ without causing portability issues? Is boost's thread library a good solution?

As a sidenote - how is it even possible to implement multithreading as a library? Isn't that something that has to be done by the compiler?

+3  A: 

In C++, yes threading is platform specific. However, many threading libraries encapsulate the nuances of threading on various platforms, providing a uniform API with which to write your threaded app, so you don't have to worry about platform specific details.

Boost threading library is a very good solution.

I also recommending checking out ACE as well.

Alan
A: 

Unfortunately C++ was not designed to be cross-platform language... Boost might be the the closest thing you'll get, in solving your portability issues. Latest version has support for threads. You might also want to read through this

Hypnos
C++ *was* designed to be cross-platform, and it *is* cross platform. Proof of this is that the only other language that is more multi-platform is plain c, because it is present in micro-controlers. If you write some code that uses only 'pure' C++ (i.e. only STL) it will run on almost anything.
Gianni
Yes, you are absolutely correct. Fast typing is scrambling my terminology. I (of course) meant to say, that C++ is not a portable language such as java, however the source code can be written to be platform independent.
Hypnos
+1  A: 

also check out Qt

technomage
+11  A: 

If you do not have a compiler that supports C++0x yet (available with visual studio c++ 2010 for example), use boost threads. (Unless you use a framework that already supports threading, which is not the case - you wouldn't ask the question otherwise -). These boost threads became actually the standard in the brand new C++. Before that time C++ itself was thread unaware.

TBB Threading Building Blocks might also be interesting to you if you want to learn other aspects in parallel programming.

Regarding Qt: if you only want threading support it is complete overkill. It has horribly slow round trip times from compiling to result. It is really well designed thought. But not an official standard like the C++0x threads from boost. Therefore I would not take it as a first choice.

jdehaan
Thanks. All of the answers were very hepful, but this one was the most informative imo.
Cam
+1  A: 

To offer a suggestion different from Boost, I use Pthreads (or Pthreads-Win32 on Windows). It's a very do-it-yourself barebones library, but provides you with all you need and nothing else. It's very lightweight compared to Boost and you can easily find C++ wrappers around it to give you higher level abstractions.

Victor Liu
The threading library from boost is a template "header only" library. It doesn't create any big overhead. Ok the bunch of files needed might be huge, but in the final result you will only have a few bytes from the template instantiation.
jdehaan
@jdehaan: Can you expand on what you mean by "template "header only" library"?
Cam
I must admit I am quite surprised too by the "header only". This: `libboost_thread-vc100-mt-gd-1_43.lib` doesn't look like a header.
Matthieu M.
Oh, I think I probably messed up with the shared_ptr, unique_ptr, weak_ptr stuff which are header-only (@incrediman: no lib or dll needed, only `*.hpp` files). Sorry you are right, then it isn't that small... The DLL comes with thread and mutex classes and a lot more.
jdehaan
Here is a good thread that discusses the pros and cons from the experts regarding header-only or not for parts of boost threads: http://old.nabble.com/-threads--making-parts-of-Boost.Threads-header-only-td22926099.html
jdehaan
+4  A: 

Let's start backward:

How is it possible to implement threading in a library ?

It isn't, at least not in (pure) C++. This requires language support (the compiler is only an implementation).

At the moment 2 things are used:

  • assembly code for some parts (like in the pthread library)
  • specific compiler instructions for others (dependent on the compiler and platform)

Both are brittle and require a tremendous amount of work for portability. Basically it means lot of #ifdef portions in the code to test for the compiler and targetted architecture, test for the support of some directives etc...

That is why it was deemed necessary to add threading support in C++0x.

How do I do multithreading ?

Even before you choose a library, you should choose a method. There are 2 ways of programming multithreaded applications (and you can combine them):

  • Communicate by sharing: this means using mutexes, atomic operations, etc... you can use pthread on Linux platforms, but I would recommend Boost.Thread (among others) for its portability.
  • Share by communicating: more recent, and adapted to distributed computations, this stems from the functional languages. This means passing messages from one thread to another and not sharing any resources. You can use FastFlow or Intel's Thread Building Blocks aka TBB.

You can conceivably merge the two, but it would be better not to. Personally I have found the description of FastFlow totally awesome: it encourages lock-free programming. Also, the main advantage of the second method is that it's better adapted to multi-processes programming and scales to distributed environments.

To begin with, I would recommend focusing on either one and build some applications with it. When you're comfortable you may try out the other, but be ready to start anew, they are that different.

Matthieu M.
Its not up to the compiler to support threads, it up to the OS. The way to do it in pure C++, for example, is include pthreads headers, use its functions and link to its lib. The compiler knows nothing about pthreads itself.
Gianni
Well, I would say that using an assembly-based library is not using pure C++ ;) I will correct the compiler thing though, I meant language.
Matthieu M.
@Matthieu what I meant is that, and app actually just asks the OS for a thread, and its up to the OS to create and init the thread. The ASM or built-in compiler functions (which just mean more ASM) is used only for atomics. Mutexes, Semaphores, Threads themselves are all up to the OS.
Gianni
And how is your second method more recent? IPC is basically that. Note you can do it between processes, not just threads.
ninjalj
@Gianni the compiler still needs to be aware of the existence of the possibility of multiple threads in order to not apply optimizations or reorderings that would be safe with a single thread but aren't safe with multiple threads.
Logan Capaldo
@Logan I may be wrong, but I think that the compiler (gcc actually) doesn't know that, that's why it has atomics and memory barriers, which the programmer has to put in himself.
Gianni
@Gianni Indeed. Standards don't say anything about the memory model (this may change with C++0x). See http://gcc.gnu.org/ml/gcc/2007-10/msg00266.html and http://gcc.gnu.org/ml/gcc/2007-10/msg00275.html
ninjalj
@Gianni atomics and memory barriers are exactly the sort of things you you extend the language with to give the compiler that information. It is indeed (partially) up to the compiler to support threads.
Logan Capaldo
@Logan Yes, your right, I guess it depends on a point of view. To me, that's just sync suff, which is used for IPC, HW access and threads. Whereas starting a new 'pid' is all up to the OS.
Gianni
+1  A: 

you might also consider openmp http://openmp.org. Many compilers support it, including MS, GCC/G++ and Intel. Although you don't get explicit control of threads, its higher level abstraction of parallelism is sometimes more efficient (at coding time as well as runtime), and the code is much easier to understand. It's not going to help you much if you're doing GUI work, but for scalable computation it's worth a look.

phlip
+1  A: 

The Boost Threading Library is probably the best place to start for C++. Gives you threading contructs, as well as all the mutexes and control objects you need to write a real working multithreaded application.

Conradaroma
A: 

If you're doing this out of interest to improve your knowledge of different programming models and language skills then the Boost library would be a fine way to go. However I would think long and hard about actually building any production applications using multi-threaded C++.

C++ is challenging enough at times to attain correctness without adding the considerable complexity of shared memory multi-threading. Even the most seasoned programmers would agree that multi-threaded programs are extremely hard to reason about and get right. Even the simplest programs can quickly become hard to test and debug when multi-threaded.

Imperative languages such as C++ or Java or C# (with their mutable variables, shared memory and locking/signalling primitives) are very often the least approachable way to try to build multi-threaded applications. There are usually perfectly good single threaded implementation options to accomplish most user-space (as opposed to kernel or embedded) application problems, including on multi-core machines.

If you really want to build reliable "multi-threaded" applications I would suggest you check out functional languages like Erlang, Haskell, F# or Clojure.

bjg