Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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++ QThread始终只剩下一个线程_C++_Qt_Qthread - Fatal编程技术网

C++ QThread始终只剩下一个线程

C++ QThread始终只剩下一个线程,c++,qt,qthread,C++,Qt,Qthread,这是我的帖子: class calThread : public QThread { Q_OBJECT public: calThread(QList<int> number); ~calThread(); void run(); QList<int> cal(QList<int> input); signals: void calFinished(QList<int> result); };

这是我的帖子:

class calThread : public QThread
{
    Q_OBJECT
public:
    calThread(QList<int> number);
    ~calThread();
    void run();
    QList<int> cal(QList<int> input);

signals:
    void calFinished(QList<int> result);   
};

void calThread::run()
{
     output = cal(number);
     emit calFinished(output);
     sleep(1);
}
“为什么总是留下一根线?”

为什么不呢?线程调度完全是操作系统的一时兴起。根本不能保证任何线程都能获得任何CPU资源的“公平共享”。您需要分配小块工作,并让它们自动分布在工作线程中
QtConcurrent::run
,而QtConcurrent框架通常提供了一种简单的方法来实现这一点。只要传递给
run
mapReduce
等的工作块大小合理(例如,取0.1到1s),池中的所有线程都将在每个线程的十分之二秒内完成

对您观察到的行为的部分解释是,已经在给定内核上运行的线程更有可能在同一内核上重新调度,以利用那里的热缓存。如果四个内核中有三个几乎连续运行线程,那么第四个线程通常会与GUI线程共享内核,如果GUI不空闲,那么运行速度必然会变慢。如果GUI线程正忙于处理来自其他线程的结果,那么该核心上的计算线程将被饿死也就不足为奇了。这实际上是调度线程的最省电、最省时的方法,开销最少

只要你给线程一小部分的工作要做,并在准备就绪的基础上分发它们(就像
QtConcurrent
所做的那样),它也将导致最小的挂钟运行时间。如果调度程序强制执行“公平”的重新调度,那么长时间运行的线程将大致在同一时间完成,但完成作业将花费更多的时间和精力。现代调度程序使您能够最高效地运行作业,但您必须设置作业以利用这一点


在某种程度上,您的调度程序正在帮助您改进代码,以提高资源效率。这是一件好事。

您的计算机上有多少内核?您是否尝试在cal函数中为输入列表中的每个项目打印调试信息,以查看可能发生的情况?看起来您的任务会被mapReduce很好地处理,请查看@Q-B我使用的是四核cpu。调试结果已发布。您没有像PLINQ中那样的确定性屏障(无论如何都不能保证单个任务的执行顺序)。这是糟糕的设计。您强制执行一个只能由“正确”线程完成工作的方案。相反,要设计一些东西,这样无论线程如何获得CPU时间,都可以完成需要完成的工作。这样,您将永远不会陷入所有工作都必须由一个线程完成的情况。事实上,gui总是很忙,因为我的线程总是向gui发送显示进度的信号。
    calThread* worker3 = new calThread(numberList);
    connect(worker3, SIGNAL(calFinished(List<int>)), this, SLOT(handleResult(List<int>)));
    connect(worker3, SIGNAL(finished()), worker3, SLOT(deleteLater()));
    worker3->start();
inputThread0 item numbers: 1736 
inputThread1 item numbers: 1736 
inputThread2 item numbers: 1736 
inputThread3 item numbers: 1737 

"20:29:58" Thread 0 Thread ID 0x7f07119df700
"20:29:58" Thread 3 Thread ID 0x7f06fc1d3700
"20:29:58" Thread 1 Thread ID 0x7f06fd1d5700
"20:29:58" Thread 2 Thread ID 0x7f06fc9d4700
"20:29:58" Thread 0 Thread ID 0x7f07119df700
"20:29:58" Thread 1 Thread ID 0x7f06fd1d5700
….............................
//Most of them are Thread 0,1,2 afterward
….............................
"20:29:58" Thread 1 Thread ID 0x7f06fd1d5700
// This is last Thread from thread 0,1,or2
// It takes less than one second to finish
"20:29:59" Thread 3 Thread ID 0x7f06fc1d3700
"20:29:59" Thread 3 Thread ID 0x7f06fc1d3700
"20:29:59" Thread 3 Thread ID 0x7f06fc1d3700
"20:29:59" Thread 3 Thread ID 0x7f06fc1d3700
….................................
// Only Thread 3 left
"20:30:17" Thread 3 Thread ID 0x7f06fc1d3700
// This last thread takes 19 second to finish