C++多线程问题

发布于 2024-11-05 01:10:55 字数 613 浏览 0 评论 0原文

我最近正在制作一个非常简单的应用程序,只是将矩阵效果打印到控制台。所以我用一个非常易于使用的函数void drawLine(int startX, int startY, int lineLength,int speed);来实现它。现在的问题是它一次只打印一行。当然,我需要使这个应用程序成为多线程,但我发现自己很挣扎,因为我从未在 C++ 中这样做过,只在 C# 中这样做过,而且与 C++ 相比,在 C# 中这很容易做到。

我做了一些研究,尝试使用 CreateThread 创建 3 个线程,然后使用 WaitForMultipleObjects 启动它们。但输出非常奇怪并且看起来不正确。即使这可以正常工作,它也会导致我遇到下一个问题。想象一下,我想在控制台上启动 15 行以上,这是否意味着我需要创建 15 个不同的线程?

请注意,这并不是什么重要的事情,它只是我刚刚创建的东西,因为我很无聊,也因为我想学习 C++ 的线程。我当然可以使用 boost 库,但我想为自己创建一个不使用它的示例。

下面是一个只有 1 个线程的屏幕截图,只是为了让它更清楚: 在此处输入图像描述

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 correct. 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:
enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巡山小妖精 2024-11-12 01:10:55

这个问题与线程无关——或者更确切地说,这个问题绝对不需要线程。一个简单的面向对象的设计应该很容易让你在一个框架中绘制多条线——你认为单线程游戏如何在一个框架中绘制数千个或更多的顶点?

更重要的是,只有最新的(Windows Vista 或更高版本)Windows 渲染器才允许多线程渲染,即 Direct2D/Direct3D11。其他渲染器(例如 D3D9)持有阻止多线程渲染的内部锁,因为它们的运行时和图形驱动程序无法处理它。

如果您确实拥有像 Direct2D 这样的并发安全渲染器,那么从多个线程进行渲染应该相对简单,并且您不应该使用本机 Windows 线程 API。我发现您正在使用 Visual Studio 2010 - 使用并发运行时。 WinAPI 仅提供线程原语 - 直接使用它们类似于用汇编程序编写。至少使用boost::thread。线程实际上与实现无关,它与良好的设计有关,而设计与您使用什么库来实现它无关。

编辑:等一下,您正在使用控制台吗?这根本不是线程安全的。这太疯狂了。控制台的存在是为了最基本的 I/O,而不是为了这个。最有可能的是,C# 只是为您同步它,而 C++ 则不然。

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.

像你 2024-11-12 01:10:55

函数drawLine可能是一个循环,其中包含一个定位光标的命令,然后打印字符(如果没有,则向我们显示函数代码)。这两条指令必须按顺序执行,其他线程中的其他指令不会干扰执行。因此,引入一个锁(又名临界区)来保证这两条指令有序执行。函数的顺序是这样的:

EnterCriticalSection
SetConsoleCursorPosition
SetConsoleTextAttribute
WriteConsole
LeaveCriticalSection

临界区在所有线程之间共享。

单线程方法也是一种选择,因为矩阵串不交互。简单的解决方案是这样的:将所有矩阵字符串的数据保存在内存中,然后在单线程中一个接一个地绘制它们。一切绳索拉好后,小睡一会。希望动画看起来合理。

更复杂的解决方案是使用简单的解决方案,但要有两个屏幕缓冲区(使用CreateConsoleScreenBuffer和SetConsoleActiveScreenBuffer),并不断切换它们以实现即时绘制。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文