Qt里线程中while循环阻塞信号槽问题

iperf 2021-02-13 10:15:37
各位:
遇到一个问题一直迷惑,请教一下:
下面是写的一个测试类
.h
class WorkPro : public QObject
{
Q_OBJECT
public:
explicit WorkPro(QObject *parent = nullptr);
~WorkPro();
void StopThread();

signals:
void reaustReadySignal(int);
public slots:
void DoWork();
void OnReceivedThreadOperate(int);
private:
QMutex m_Mutex;
bool m_bThreadRunFlag;

.cpp相关代码
void WorkPro::StopThread()
{
m_bThreadRunFlag = false;
}

void WorkPro::DoWork()
{
static int iCount =0;
while(m_bThreadRunFlag)
{
qDebug()<<"Run DoWrok..."<<QThread::currentThread();
iCount++;
emit reaustReadySignal(iCount);
QThread::msleep(1000);

}
}
void WorkPro::OnReceivedThreadOperate(int threadOpera)
{
qDebug()<<"Recvd OnReceivedThreadOperate";
if(threadOpera == 0)
{
qDebug()<<"Pause Thread";
}
else
{
qDebug()<<"Resume Thread";
}
}



在对话框类中使用该类,点击按钮触发:

void Dialog::on_startBTN_clicked()
{
m_pWork = new WorkPro();
m_pWork->moveToThread(&m_workThread);
connect(&m_workThread, &QThread::finished, m_pWork, &QObject::deleteLater);
connect(&m_workThread, &QThread::started, m_pWork, &WorkPro::DoWork);
connect(m_pWork,&WorkPro::reaustReadySignal,this,&Dialog::OnReceivedThreadData);
connect(this,SIGNAL(threadOperateSignal(int)),m_pWork,SLOT(OnReceivedThreadOperate(int)));
m_workThread.start();
m_bThreadPauseFlag = true;

}
void Dialog::on_pauseBTN_clicked()
{
if(m_workThread.isRunning())
{
if(m_bThreadPauseFlag)
{
emit threadOperateSignal(0);// 0 暂停
qDebug()<<"Send Pause Signal";
ui->pauseBTN->setText("恢复");
m_bThreadPauseFlag = false;
}
else
{
emit threadOperateSignal(1);// 0 暂停
qDebug()<<"Send Resume Signal";
ui->pauseBTN->setText("暂停");
m_bThreadPauseFlag = true;
}
}
}

问题是:
按钮点击暂停触发on_pauseBTN_clicked()函数
这里面发送的信号threadOperateSignal,我在WorkPro类中确收不到,
原因应该是WorkPro中的DoWork()槽里使用了while循环,
迷惑的是我不是在循环里sleep了吗?sleep 不是会把CPU时间片占用权交出来,
这样事件循环不是有机制执行了?
还是说sleep本身阻塞的就是事件循环?
事件循环不是QObject控制的么?这个强大的一个类,怎么能随便就会被一个子线程的while循环给阻塞了呢?
...全文
3341 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
atuexe 2021-02-25
  • 打赏
  • 举报
回复
可以在WorkPro类里增加一个任务队列,在线程主循环中检测任务队列,如果存在任务就执行对应的任务。否则可以Sleep。Dialog类就是往队列增加你想要的任务。
iperf 2021-02-22
  • 打赏
  • 举报
回复
谢谢,
我主要想知道大家都是怎么做的,在Qt里 有while循环时,如何进行与其它线程的通讯
因为一用Qt 就首先想到用信号槽,就存在阻塞的情况,除了QCoreApplication::processEvents,还有别的办法么?
还是直接传递类对像指针,通过 对像来调用方法实现?
  • 打赏
  • 举报
回复
不会的,要调用QCoreApplication::processEvents 才能在while里维持消息循环
iperf 2021-02-14
  • 打赏
  • 举报
回复
网上也看到有说 线程+定时器,这样感觉不是太好吧?
iperf 2021-02-14
  • 打赏
  • 举报
回复 1
版主你好,这个QCoreApplication::processEvents我试用了一下,
虽然用了它可以触发到 槽函数,但是有一个很好的问题:
槽函数的触发的时间 会 跟 while循环 里的sleep有关系,
如果我在while里sleep了2秒,槽函数的触发延迟会很明显,
所以这个方式感觉不太好。

movetothread方式的线程里+while循环 大家一般都是怎么解决这种2个线程间通讯的呢?比如我2个线程都是 while循环?
(继承QThread方式的线程倒是不存在阻塞槽函数的问题,因为那种方式其它槽函数都属于主线程,run里+while并不会影响到)
qq_24803171 2023-04-23
  • 举报
回复 1
@iperf 博主解决这个问题没? 我也遇到了
Green__hand__1 2023-04-23
  • 举报
回复
@qq_24803171 哥们,解决了吗,我正好也遇到这个问题了

16,819

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧