Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 等待条件变量加入的线程会发生什么情况?_C++_Multithreading_Qt - Fatal编程技术网

C++ 等待条件变量加入的线程会发生什么情况?

C++ 等待条件变量加入的线程会发生什么情况?,c++,multithreading,qt,C++,Multithreading,Qt,我有一个名为TThreadpool的类,它包含std::vector>类型的成员池,具有以下析构函数: ~TThreadpool() { for (size_t i = 0; i < pool.size(); i++) { assert(pool[i].joinable()); pool[i].join(); } } ~TThreadpool(){ 对于(size_t i=0;i

我有一个名为
TThreadpool
的类,它包含
std::vector>
类型的成员池,具有以下析构函数:

~TThreadpool() {
    for (size_t i = 0; i < pool.size(); i++) {
        assert(pool[i].joinable());
        pool[i].join();
    }
}
~TThreadpool(){
对于(size_t i=0;i
我确信,当调用析构函数时,所有线程都在等待一个条件变量(由always false谓词控制的伪唤醒),可连接输出为true

运行线程的简化示例如下:

void my_thread() {
    std::unique_lock<std::mutex> lg(mutex);
    while (true) {
        my_cond_variable.wait(lg, [] {
            return false;
        });
        # do some work and possibly break, but never comes farther then wait 
        # so this probably should not matter
    }
}
void my_thread(){
std::唯一锁lg(互斥);
while(true){
my_cond_变量。wait(lg,[]{
返回false;
});
#做一些工作,可能会休息,但永远不要再等了
#所以这可能不重要
}
}
为了检查正在运行的线程,我启动了
top-H
。在程序开始时,有
pool.size()
threads+1个线程,其中
TThreadpool
本身存在。令我惊讶的是,加入这些活动线程并没有将它们从top给出的线程列表中删除。这是预期的行为吗

(最初,我的程序有点不同——我使用qt制作了一个简单的ui应用程序,它使用运行在ui线程中的threadpool和threadpool控制的其他线程,并在关闭ui窗口时调用了线程连接,但QtCreator说我的应用程序在关闭窗口后仍然工作,要求我用c关闭它鲁莽。这让我检查了线程的状态,结果发现它和qt无关。虽然我添加了这个,以防我错过了qt的一些明显细节)

过了一会儿,我尝试不断言joinable,而是将其打印出来,发现Threadpool析构函数中的循环从未比第一次join移动得更远——我没有预料到,也无法解释join()的行为
不会对子线程执行任何操作——它所做的只是阻止,直到子线程退出。它只会对调用线程产生影响(即阻止其进程)。子线程可以继续运行任意时间(尽管通常您希望它快速退出,以便调用
join()的线程)
不会被阻塞很长一段时间——但这取决于您的实施)

令我惊讶的是,加入这些活动线程并不会将它们从top提供的线程列表中删除。这是预期的行为吗

这表明线程仍在运行。在线程上调用
join()
不会对正在运行的线程产生任何影响;只需调用线程即可 等待被调用的线程退出

发现Threadpool析构函数中的循环在第一次连接之前从未移动过

这意味着第一个线程还没有完成,所以其他线程也没有被加入(即使它们已经退出)

但是,如果线程功能实现正确,那么第一个线程(以及池中的所有其他线程)最终应该完成并运行
join()
调用应该返回(假设池中的线程应该退出,但通常不需要这样做)。 根据应用程序的不同,您可以简单地使线程永远运行)

因此,似乎存在某种死锁或等待某个资源占用一个或多个线程。因此,您需要运行调试器。 这将非常有用


您还可以尝试减少线程数(例如2个),看看问题是否变得可重现/明显,然后您可以增加线程数。

欢迎这样做!您如何向线程发出退出的信号?主线程是否设置了标志或条件,指示它们应从
my_thread()返回