I'm developing an application in C++11 which uses SDL as a library. I'm planning to add multithreaded support for my app. Is there any difference whether to use SDL_Thread or std::thread in my application?
Unless you're using a part of the SDL API that specifically requires SDL's thread handle type, you're better off using C++'s std::thread. The API is more idiomatic (e.g. the constructor allowing you to forward arguments to start function) and does not tie that code to what SDL provides.
The reason I mention the handle is if you actually need to pass an SDL_Thread *, there is no way to query for handle to the current thread. Granted std::thread does not provide this either, but since the interface is richer, it makes more sense to use.
Edit: Both interfaces seem to draw heavily from POSIX threads, but with one exception. std::thread does not have a built-in cancellation function. Normally, you don't want to kill a thread anyway without any sort of cleanup, but it is worth mentioning.
Related
I am new to concurrent programming. As I was going through the topics I got confused between Synchronizations, thread safe collections, atomic wrapper classes, locks.
Locks and Synchronization do same work by making a piece of code thread safe. Why do we need thread safe collections or atomic wrapper classes then? As locking will enable only a single thread to access the code and won't let collections or primitive types to be thread unsafe.
This is a very wide question that you're asking. Problem is, not all of these things have a single, strict definition. For example, thread-safe collections might use various forms of synchronization (like e.g. locks or atomic operations) to achieve thread-safety. However, not even the term "thread-safe" is well-defined!
However, there is one thing you got wrong surely: Synchronization is the goal, while locks, mutexes, atomics etc are means to achieve that. Synchronization just means that different threads access resources in a synchronized way. In other words, they coordinate access so that they don't badly interact with each other. BTW: I'm talking here about threads, but the different entities could also be processes or even different computers, but let's keep it simple at first.
Now, you ask about the use of "thread safe collections or atomic wrapper classes" and why they are required at all. The answer is pretty simple, these things provide different interfaces or services on a higher level. For example, when I have a FIFO connecting two threads, it doesn't matter how they synchronize access to the underlying queue. If the interface for the two threads is implemented properly, you get certain guarantees. Doing so manually with just locks is possible but complicated, so providing these as high-level building blocks in addition to the low-level primitives just makes software development easier and the results more reliable.
Lastly, one advise for further questions: As initially mentioned, not all terms have a universal meaning associated with them. Therefore, it would help if you provided additional info, like in particular the programming language you intend to use.
Because you need to be careful when using synchronization. If you abuse of it, you may have performance issues. Using thread-safe collections when possible is usually better for performance and you make sure that you haven't errors or deadlocks.
I have source code for USB communication ("USBThread class") written in Borland C++ and uses Visual Component Library("vcl.h").
Now my task is to port that to Visual C++, because we did not buy Borland C++.
But this "USBThread class" has inheritance from a base class in "vcl.h", called "TThread".
May I ask , in Visual C++, What kind of base class I can use to substitute "TThread' as new inheritance source?
The original code uses "WaitFor" and "Terminate" methods coming TThread,
I do not know how to implement these two menthods with Visual C++.
Thanks!
This is likely to be a difficult exerice imo but it looks like Boost.Thread using join for WaitFor and interrupt for Terminate would get you started.
I am basing this on review of the docs for VCL found here. I say this is likely to be difficult because VCL may have behaviour that is undocumented or otherwise unexpected.
Although you could translate the VCL's TThread class into C++, it would not work very well because it relies on some Delphi semantics that simply do not translate to C++ at all (in particular the TObject::AfterConstruction() method). You are best off simply re-writing USBThread to use Win32 thread functions directly, namely CreateThread() and WaitForSingleObject(). For Terminate(), you simply set a bool flag somewhere that your thread procedure can look at periodically and stop its work when set to true.
Having recently learned Grand Central Dispatch, I've found multithreaded code to be pretty intuitive(with GCD). I like the fact that no locks are required(and the fact that it uses lockless data structures internally), and that the API is very simple.
Now, I'm beginning to learn pthreads, and I can't help but be a little overwhelmed with the complexity. Thread joins, mutexes, condition variables- all of these things aren't necessary in GCD, but have a lot of API calls in pthreads.
Does pthreads provide any advantages over GCD? Is it more efficient? Are there normal-use cases where pthreads can do things that GCD can not do(excluding kernel-level software)?
In terms of cross-platform compatibility, I'm not too concerned. After all, libdispatch is open source, Apple has submtited their closure changes as patches to GCC, clang supports closures, and already(e.x. FreeBSD), we're starting to see some non-Apple implementations of GCD. I'm mostly interested in use of the API(specific examples would be great!).
I am coming from the other direction: started using pthreads in my application, which I recently replaced with C++11's std::thread. Now, I am playing with higher-level constructs like the pseudo-boost threadpool, and even more abstract, Intel's Threading Building Blocks. I would consider GCD to be at or even higher than TBB.
A few comments:
imho, pthread is not more complex than GCD: at its basic core, pthread actually contains very few commands (just a handful: using just the ones mentioned in the OP will give you 95%+ of the functionality that you ever need). Like any lower-level library, it's how you put them together and how you use it which gives you its power. Don't forget that the ultimately, libraries like GCD and TBB will call a threading library like pthreads or std::thread.
sometimes, it's not what you use, but how you use it, which determines success vs failure. As proponents of the library, TBB or GCD will tell you about all the benefits of using their libraries, but until you try them out in a real application context, all of it is of theoretical benefit. For example, when I read about how easy it was to use a finely-grained parallel_for, I immediately used it in a task for which I thought could benefit from parallelism. Naturally, I, too, was drawn by the fact that TBB would handle all the details about optimal loading balancing and thread allocation. The result? TBB took five times longer than the single-threaded version! But I do not blame TBB: in retrospect, this is obviously a case of a misuse of the parallel_for: when I read the fine-print, I discovered the overhead involved in using parallel_for and posited that in my case, the costs of context-switching and added function calls outweighed the benefits of using multiple threads. So you must profile your case to see which one will run faster. You may have to reorganize your algorithm to use less threading overhead.
why does this happen? How can pthread or no threads be faster than a GCD or a TBB? When a designer designs GCD or TBB, he must make assumptions about the environment in which tasks will run. In fact, the library must be general enough that it can handle strange, unforseen use-cases by the developer. These general implementations will not come for free. On the plus-side, a library will query the hardware and the current running environment to do a better job of load-balancing. Will it work to your benefit? The only way to know is to try it out.
is there any benefit to learning lower-level libraries like std::thread when higher-level libraries are available? The answer is a resounding YES. The advantage of using higher-level libraries is, abstraction from the implementation details. The disadvantage of using higher-level libraries is also abstraction from the implementation details. When using pthreads, I am supremely aware of shared state and lifetimes of objects, because if I let my guard down, especially in a medium to large size project, I can very easily get race conditions or memory faults. Do these problems go away when I use a higher-level library? Not really. It seems like I don't need to think about them, but in fact, if I get sloppy with those details, the library implementation will also crash. So you will find that if you understand the lower-level constructs, all those libraries actually make sense, because at some point, you will be thinking about implementing them yourself, if you use the lower-level calls. Of course, at that point, it's usually better to use a time-tested and debugged library call.
So, let's break down the possible implementations:
TBB/GCD library calls: greatest benefit is for beginners of threading. They have lower barriers to entry compared to learning lower level libraries. However, they also ignore/hide some of the traps of using multi-threading. Dynamic load balancing will make your application more portable without additional coding on your part.
pthread and std::thread calls: there are actually very few calls to learn, but to use them correctly takes attention to detail and deep awareness of how your application works. If you can understand threads at this level, the APIs of higher-level libraries will certainly make more sense.
single-threaded algorithm: let us not forget the benefits of a simple single-threaded segment. For most applications, a single-thread is easier to understand and much less error-prone than multi-threading. In fact, in many cases, it may be the appropriate design choice. The fact of the matter is, a real application goes through various multi-threading phases and single-threading phases: there may be no need to be multi-threaded all the time.
Which one is fastest? The surprising truth is, it could be any of the three of the above. To get speed benefits of multi-threading, you may need to drastically reorganize your algorithms. Whether or not the benefits outweigh the costs is highly case-dependent.
Oh, and the OP asked about cases where a thread_pool is not appropriate. Easy case: if you have a tight loop that does not require many cycles per loop to compute, using thread_pool may cost more than the benefits without serious reworking. Also be aware of the overhead of function calls like lambda through thread pools vs the use of a single tight loop.
For most applications, multi-threading is a kind of optimization, so do it at the right time and in the right places.
That overwhelming feeling that you are experiencing.. that's exactly why GCD was invented.
At the most basic level there are threads, pthreads is a POSIX API for threads so you can write code in any compliant OS and expect it to work. GCD is built on top of threads (although I'm not sure if they actually used pthreads as the API). I believe GCD only works on OS X and iOS — that in a nutshell is its main disadvantage.
Note that projects that make heavy use of threads and require high performance implement their own version of thread pools. GCD allows you to avoid (re)inventing the wheel for the umpteenth time.
GCD is an Apple technology, and not the most cross platform compatible; pthread are available on just about everything from OSX, Linux, Unix, Windows.. including this toaster
GCD is optimized for thread pool parallelism. Pthreads are (as you said) very complex building blocks for parallelism, you are left to develop your own models. I highly recommend picking up a book on the topic if you're interested in learning more about pthreads and different models of parallelism.
As any declarative/assisted approach like openmp or Intel TBB GCD should be very good at embarrassingly parallel problems and will probably easily beat naïve manually pthread-ed parallel sort. I would suggest you still learn pthreads though. You'll understand concurrency better, you'd be able to apply right tool in each particular situation, and if for nothing else - there's ton of pthread-based code out there - you'd be able to read "legacy" code.
Usual: 1 task per Pthread implementations use mutexes (an OS feature).
GCD:
1 task per block, grouped into queues. 1 thread per virtual CPU can get a queue and run without mutexes through all the tasks. This reduces thread management overhead and mutex overhead, which should increase performance.
GCD abstracts threads and gives you dispatch queues. It creates threads as it deems necessary taking into account the number of processor cores available.
GCD is Open Source and is available through the libdispatch library. FreeBSD includes libdispatch as of 8.1. GCD and C Blocks are mayor contributions from Apple to the C programming community. I would never use any OS that doesn't support GCD.
Is there a template that can be used to create threads when we program in
OO language ?
How to go about designing a threading package for an OO language?
Support
C++0x will support threads in the standard library.
As of now, each platform has its own way of implementing threads (Windows, POSIX) but you can use something such as boost::thread to not have to worry about platform-specific stuff.
In Java, there is a Thread class.
Methods
In general, to put a class into another thread, you will create a thread while passing that class into the thread. Then the thread will call a function in that class. Here is some pseudo-C++-code:
main()
{
Object myObject;
thread = CreateThread(threadFunction, myObject);
thread.join(); // wait for thread
}
threadFunction(Object theObject)
{
theObject.doSomething();
}
This is all simplified by the use of boost (or C++0x threads) in C++, and the Thread class in Java handles this for you.
Related Information
A large problem in threaded applications is synchronization of threads. This includes problems like race conditions and deadlocks, to name a couple.
Methods/object exist to help these problems, such as a mutex. A mutex can be locked by one thread, and any other threads that try to lock the mutex will be blocked until the original thread releases the mutex.
A semaphore is a generalized mutex.
There are other useful concepts as outlined in Eric's post.
Each framework has its own way of dealing with threads. I suggest you look up the java thread class in the the java documentation, and then perhaps look at the C++ standard headers for thread details.
Each programming language has specific ways of handling threads.
C++ relies a lot on Boost so you might wanna check that
Java
Basically everything you learn about concurrency should apply whatever the OS or language you're using. There are roughly 4 problems you must learn to avoid
Deadlocks
Livelocks
Race Conditions
Hunger
This isn't directly related to your questions but these are subjects you should learn in parallel to learning a particular syntax in a given language. Java is of course quite easy while C++ might be a little trickier, your pick
There are also a number of "well known methods" for synchronizing threads such as
Events
Locks
Monitor
Mutex
Semaphore
Barrier
...
this list goes on and on, but are basically helping "objects" or variables that will help you solve the 4 problems mentionned
In C/C++, threads are often implemented using functions. ("Start a new thread and run this function inside, destroys the thread when the function ends.")
Thread frameworks often allow to pass parameters to the function. One way of doing OO with threads is to pass the object pointer ("this") as the function parameters and then call a specific method on the object.
If you are using MFC then MFC provides some framework helper APIs to work with multi threading. Have a look at this article: Multithreading with C++ and MFC
In Java you can use the Thread class or the Executor interface, to which you can send a runnable object. Check out the java.util.concurrent package. And the concurrency trail of the Java Tutorial. Good Luck.
The main difference when it comes to OOP and multi-threading programming is that you would like your new thread to have as its start-up function a (non-static) method of an object.
Now there are a few programming models for this: implement a "Runnable" interface is the most common used one. Your class implements a standard "Runnable" interface that has a start-up method which is usually a virtual method called "run". You put your start-up code in that virtual method and when you need to spawn a thread you create a thread object (usually called Thread) and you pass to it an object of your class that implements the "Runnable" interface. Then you call the "start" method of that "Thread" object and that will take care that the start-up code you have written in your class will be run a a new thread. In this example both "Runnable" and "Thread" are provided by the chosen threading library or by the standard library/framework of the programming language of your choice. Also please note that the names of these two classes can vary.
There is a big difference between C++ and Java when it comes to multi-threading programming: C++ has not support for multi-threading as opposed to Java which has built-in support for that.
So for C++ you will need to use a specialized threading library such as Pthreads (http://en.wikipedia.org/wiki/POSIX_Threads) or more general purpose libraries such as Boost, ACE, POCO which already have support for threading. The least recommended way is to call directly the multi-threading related services of the OS.
For Java, no matter what edition you are using you will already have the support for multi-threading programming built-in.
Is there any documentation on cross thread communication in Delphi? How can I send message to the thread that doesn't have a window?
You can only send (Windows) messages to threads that implement a standard message loop, which will automatically be created once a window handle is realized.
It is however not necessary to use messages to communicate with a thread. Just let it wait on an event object (TEvent in VCL), and signal this event when you want the thread to perform a function.
But if you are new to multi-threading - don't go into all these details on your own, unless you want to for the learning effect. Just use the OmniThreadLibrary and be done with it. There's much good to be learned by digging into its internals, once you know how to use it.
Edit:
See also the answers to this question which is very similar.
Edit 2:
Regarding the comment asking "What does [OmniThreadLibrary] make easier, and at what cost?" I can only advise you to check it out for yourself - that is if you are using at least Delphi 2007. There are several samples to illustrate the concepts, but for a quick "real-life" example you could have a look at this blog post - you don't even need to install the library for that.
I do also agree that using a library for multi-threading does require a certain act of faith. OTOH making do with what the VCL provides is hardly an alternative. The sample code does still use the ill-conceived Synchronize() call. There is no support for things like thread-safe producer-consumer-queues, which are much more suited to multi-threaded programming. And if you do agree that you need a more solid fundament for your multi-threaded programs than the VCL provides - why reinvent that particular wheel?
As for the cost of using the library: You will have to time yourself whether it is fast enough for you. It does abstract the communication between threads in a good way IMHO, but every abstraction costs performance, obviously.
If you decide that it is not for you after all - write the code yourself. I did the same for Delphi 4, and I have been using that code for nearly 10 years now. And judging by the amount of bugs I found and corner cases I experienced in that time, I would definitely advise anybody new to multi-threading to not write their own library code for it. And if you really really want to, please take the rules in this posting to heart.
The question Delphi Multi-Threading Message Loop also contains a few examples of communication between threads
If you have a reference to the thread object, you can just call it direct, and have the procedure store information or update accordingly. Obviously you have to be careful to do things in a thread safe manner.
Alternatively, you could use a central control object through which the threads communicate when they aren't busy. I have an app where threads have particular purposes, and are allocated a thread-ID. Any thread can "post" a message with a message-ID and a string for parameters to another thread-ID and then get on with its work. The other thread the picks it up at its leisure, and acts accordingly.