繁体   English   中英

分离线程:忙时互斥体被破坏错误 C++

[英]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。


当然还有另外两种可能的解决方案:

  1. 不要分离线程,并在退出之前join它们main 不过,这可能并不总是可能或不希望的。

  2. main function 内部等待分离的线程退出,使用线程已退出的某种其他类型的等待或轮询机制。 这也可能不是所希望的。 如果线程在main function 检查的线程内部设置一个标志,则可能会出现问题,这可能会导致在main function 返回之前线程实际上尚未退出的竞争条件。

您的主要 function 结束 - 您的整个程序也是如此。 任何其他线程都无法阻止这一点 - 因此您必须等待它们完成(参见 std::thread::join)。 这可能就是你所需要的。 但是互斥锁是怎么回事? 所有程序资源都在程序结束时被销毁 - 你不能销毁繁忙的互斥锁(参见 std::lock_guard )

更新:注意到另一个坏事——你没有同步线程——所以生产/消费线程会有数据竞争,并且不能保证你的所有数据都被处理了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM