[英]Detached Threads: mutex destroyed while busy Error C++
我完全是 C++ 和线程的初学者。 我为我的问题做了一个非常简单的例子。 在我提供的代码中,我创建线程并分离它们。 每个线程执行不同的 function:一个包括将一个 int 推入队列,另一个读取该值并使用读取的值和函数的参数模拟长时间处理。 队列 object 受互斥体保护,因为它在两个线程之间共享。 我知道我的代码有点愚蠢,但我已经让它代表了我真正的问题,它使用分离的线程和受互斥体保护的共享队列。
这是代码:
#include <mutex>
#include <iostream>
#include <thread>
#include <queue>
using namespace std;
std::queue<int> tasks;
std::mutex m;
void push_task(int arg) {
printf("[Pushing task into the queue]");
m.lock();
tasks.push(arg);
m.unlock();
}
void process_task(int number) {
printf("[Processing task from the queue]");
m.lock();
while (tasks.empty() == false){
int task = tasks.front();
tasks.pop();
printf("[Processing...]");
std::this_thread::sleep_for(std::chrono::milliseconds((task+number)*1000)); //simulate some execution
printf("[Task has been successfully processed]");
}
m.unlock();
}
int launch_threads(int nTask, int n){
int counter = 0;
while(counter < 8){
std::thread(push_task, nTask).detach();
std::thread(process_task, n).detach();
counter++;
}
printf("[Launch Threads Ends]");
return 0;
}
int main(){
launch_threads(0, 10000);
printf("[Main Ends]");
return 0;
}
好吧,我面临的问题是我收到以下错误:
忙时被破坏的互斥锁
我已经调查并且我已经阅读(如果我错了,请纠正我)发生这种情况是因为调用 function,在我的例子中是 launch_threads(),在它内部创建的本地线程仍在运行时结束,因此互斥锁仍然可以由某个线程(很忙),给出了那个错误。 事实上,线程内部的处理并没有真正结束。
我的问题是:我怎样才能避免这个错误?
我还读到不将线程作为局部变量可能会解决问题。 在这种情况下,如果我传递一个带有参数的 function,我如何将线程声明为全局线程?
与该主题相关的额外问题:使用std::lock_guard lock(m)可以帮助避免问题吗?
先感谢您!
您启动一些线程并将它们分离。 然后让main
function 返回终止进程。 该进程终止会杀死所有线程并导致所有全局对象被破坏。
您应该只退出main
function 正在运行的线程,这让分离的线程继续在进程中运行(然后在最后一个线程退出时退出)。
目前C++标准库中没有办法退出线程,所以必须使用系统相关函数。 例如,在 POSIX 系统(如 Linux 或 macOS)中,您使用pthread_exit
function。
当然还有另外两种可能的解决方案:
不要分离线程,并在退出之前join
它们main
。 不过,这可能并不总是可能或不希望的。
在main
function 内部等待分离的线程退出,使用线程已退出的某种其他类型的等待或轮询机制。 这也可能不是所希望的。 如果线程在main
function 检查的线程内部设置一个标志,则可能会出现问题,这可能会导致在main
function 返回之前线程实际上尚未退出的竞争条件。
您的主要 function 结束 - 您的整个程序也是如此。 任何其他线程都无法阻止这一点 - 因此您必须等待它们完成(参见 std::thread::join)。 这可能就是你所需要的。 但是互斥锁是怎么回事? 所有程序资源都在程序结束时被销毁 - 你不能销毁繁忙的互斥锁(参见 std::lock_guard )
更新:注意到另一个坏事——你没有同步线程——所以生产/消费线程会有数据竞争,并且不能保证你的所有数据都被处理了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.