C++ 中的队列和线程

huangapple go评论63阅读模式
英文:

Queue and Threads in C++

问题

我尝试做的事情:

我试图创建一个程序,其目标是将元素添加到队列(在线程中),并显示有关队列的数据(可以在主函数中看到要显示的数据)。在此之前,我想从队列中删除一个元素(每两秒一次)并添加新元素(每一秒一次)。

代码:

#include <iostream>
#include <queue>
#include <thread>
#include <Windows.h>

using std::queue;
using std::cout;

void loadQueue(queue<int> &toLoad)
{
for(int i = 0; i < 100; i++)
{
toLoad.push(i);
Sleep(1000);
}
}

int main(void)
{
queue<int>toLoad;
std::thread(loadQueue, std::ref(toLoad));

while(true)
{
    cout &lt;&lt; &quot;队列大小:&quot; &lt;&lt; toLoad.size() &lt;&lt; &#39;\n&#39; &lt;&lt; &#39;\n&#39;; 

    cout &lt;&lt;&quot;首元素:&quot; &lt;&lt; toLoad.front() &lt;&lt; &#39;\n&#39; &lt;&lt; &#39;\n&#39;;

    cout &lt;&lt;&quot;尾元素:&quot; &lt;&lt; toLoad.back() &lt;&lt; &#39;\n&#39;;
    toLoad.pop();
    Sleep(2000);
}

}


有关错误:
当我启动程序时,我什么都看不到。程序立即关闭。Visual Studio 显示给我这个消息:

[![Visual Studio启动程序后显示的错误](https://i.stack.imgur.com/YSJjc.png)](https://i.stack.imgur.com/YSJjc.png)
英文:

What i tried to do:

I tried to make program witch goal is add elements to the queue (in thread) and display data about queue (You can see data to display in main). Before that i wanted to delete one element form queue (every two seconds) and adding new element (every one second).

Code

#include &lt;iostream&gt;
#include &lt;queue&gt;
#include &lt;thread&gt;
#include &lt;Windows.h&gt;

using std::queue;
using std::cout;

void loadQueue(queue&lt;int&gt; &amp;toLoad)
{
    for(int i = 0; i &lt; 100; i++)
    {
        toLoad.push(i); 
        Sleep(1000);
    }
}

int main(void)
{
    queue&lt;int&gt;toLoad;
    std::thread(loadQueue, std::ref(toLoad));

    while(true)
    {
        cout &lt;&lt; &quot;SIZE OF QUEUE : &quot; &lt;&lt; toLoad.size() &lt;&lt; &#39;\n&#39; &lt;&lt; &#39;\n&#39;; 

        cout &lt;&lt;&quot;FRONT :&quot; &lt;&lt; toLoad.front() &lt;&lt; &#39;\n&#39; &lt;&lt; &#39;\n&#39;;

        cout &lt;&lt;&quot;BACK : &quot; &lt;&lt; toLoad.back() &lt;&lt; &#39;\n&#39;;
        toLoad.pop();
        Sleep(2000);
    }

}

About error

When I start program i don't see enything. Program close right away. Visual Studio show me this messege:

C++ 中的队列和线程

答案1

得分: 7

std::thread 在附加到执行线程时无法销毁。在你的情况下,在这行代码中引入了一个临时对象,它会在表达式完成时销毁:

std::thread(loadQueue, std::ref(toLoad));

你需要分离线程并让它自行运行:

std::thread{ loadQueue, std::ref(toLoad) }.detach();

或者命名变量并在工作进行时保持其存活:

std::thread thread{ loadQueue, std::ref(toLoad) };

由于主线程有无限循环,此线程将永远不会被销毁。但理想情况下,你应该在某处加入该线程,例如在 main 函数的末尾:

while(true)
{
   ... 
}
thread.join();

此外,请注意,std::queue 不是线程安全的类,因此你必须手动同步对它的访问,否则你的代码中会出现竞争条件,这在标准中是未定义的。

英文:

std::thread cannot be destroyed while it's attached to an execution thread. In your case, however, you introduce a temporary in this line of code which gets destroyed the moment the expression finishes:

std::thread(loadQueue, std::ref(toLoad));

You either need to detach the thread and let it be:

std::thread{ loadQueue, std::ref(toLoad) }.detach();

or name the variable and keep it alive while your work is happening:

std::thread thread{ loadQueue, std::ref(toLoad) };

Since you have infinite loop in the main thread, this thread will never be destroyed, but ideally you want to join it somewhere, e.g. at the end of the main function:

while(true)
{
   ... 
}
thread.join();

Also be advised, that std::queue is not a thread-safe class, so you have to manually synchronise access to it, otherwise you have race condition in you code which is UB by the standard.

huangapple
  • 本文由 发表于 2023年4月11日 03:48:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75980230.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定