C++ multi-threading question
I was recently making a very simple application that just printed matrix-effect out to the console. So I made it in a very easy to use function void drawLine(int startX, int startY, int lineLength,int speed);
. The problem now is that it only prints one line at a time. Of course I need to make this application multi-threaded, but I found myself struggling because I've never done this in C++, only in C# and in C# it is very easy to do compared to C++.
I did some research and tried to create 3 threads with CreateThread
and then launching them with WaitForMultipleObjects
. But output is very weird and doesn't seem co开发者_运维百科rrect. And it also leads me to next problem even if this would work correctly. Imagine that I want to launch 15+ lines on my console, does that mean that I need to create 15 different threads?
Note that this is not something important, it's just something I just created because I was bored and also because I want to learn threading with C++. I can, of course use boost libraries, but I want to create example for myself w/o using it.
Here is a screenshot with 1 thread only just to make it more clear:
This problem has nothing to do with threading- or rather, this problem absolutely doesn't require threading. A simple object-orientated design should easily allow you to draw multiple lines in a frame- how do you think single-threaded games draw thousands or more of vertices in a frame?
More importantly, only recent (Windows Vista or later) renderers for Windows allow multi-threaded rendering- that is, Direct2D/Direct3D11. Other renderers like D3D9 hold internal locks that prevent multi-threaded rendering because their run-times and the graphics drivers can't handle it.
If you do have a concurrency-safe renderer like Direct2D, then it should be relatively trivial to render from multiple threads- and you shouldn't be using the native Windows threading API. I see that you're using Visual Studio 2010- use the Concurrency runtime. The WinAPI only provides threading primitives- using them directly would be akin to writing in assembler. At least use boost::thread
. Threading is not really about implementation, it's about good design, and design is irrelevant of what library you use to implement it.
Edit: Wait a minute, you're using the console? That's not thread-safe at all. That's insanity. The console exists for the most basic I/O ever, not for this. What's most likely is that C# just synchronizes it for you and C++ doesn't.
The function drawLine is probably one loop with a command to position the cursor, following with printing the character (if not then show us the function code). Those two instructions must execute sequentially, without some other instruction from other thread messing with the execution. So, introduce a lock (AKA critical section) that will guarantee that these two instructions execute orderly. Order of functions would be something like this:
EnterCriticalSection
SetConsoleCursorPosition
SetConsoleTextAttribute
WriteConsole
LeaveCriticalSection
The critical section is shared among all threads.
Single threaded approach is also an option, because the matrix strings don't interact. Simple solution would be something like this: Keep in memory data of all matrix strings, and just draw them one after another, in single thread. Sleep a little after all strings are drawn. Hopefully, the animation will look plausible.
More complex solution would be to use simple solution, but to have two screen buffers (with CreateConsoleScreenBuffer and SetConsoleActiveScreenBuffer), and switch them constantly to achieve instant drawing.
精彩评论