gpt4 book ai didi

multithreading - 如何实现线程的频繁启动/停止(QThread)

转载 作者:行者123 更新时间:2023-12-05 01:13:37 24 4
gpt4 key购买 nike

我需要使用按钮非常频繁地启动和停止线程。我正在使用 Qt。最近学会了创建worker的QObject,并将其移动到QThread的对象中,作为Qt中实现线程的正确方式。以下是我的实现...

worker .h

class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = 0);
void StopWork();
void StartWork();
bool IsWorkRunning();

signal:
void SignalToObj_mainThreadGUI();

public slots:
void do_Work();

private:
void Sleep();

volatile bool running,stopped;
QMutex mutex;
QWaitCondition waitcondition;
};

worker .cpp
 worker::worker(QObject *parent) :
QObject(parent),stopped(false),running(false)
{
}

void worker::do_Work()
{
running = true;
while(!stopped)
{
emit SignalToObj_mainThreadGUI();
Sleep();
}
}

void worker::Sleep()
{
mutex.lock();
waitcondition.wait(&mutex,10);
mutex.unlock();
}

void worker::StopWork()
{
mutex.lock();
stopped = true;
running = false;
mutex.unlock();
}

void worker::StartWork()
{
mutex.lock();
stopped = false;
running = true;
mutex.unlock();
}

bool worker::IsWorkRunning()
{
return running;
}

主窗口.h
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

public slots:

private slots:
void on_pushButton_push_to_start_clicked();

void on_pushButton_push_to_stop_clicked();

private:

Ui::MainWindow *ui;
worker *myWorker;
QThread *WorkerThread;
};

主窗口.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

myWorker = new worker;
WorkerThread = new QThread;
myWorker.moveToThread(WorkerThread);

QObject::connect(WorkerThread,SIGNAL(started()),myWorker,SLOT(do_Work()));
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::on_pushButton_push_to_start_clicked()
{
if(!myWorker.IsWorkRunning())
{
myWorker->StartWork();
WorkerThread->start();
}
}

void MainWindow::on_pushButton_push_to_stop_clicked()
{
if(myWorker.IsWorkRunning())
{
myWorker->StopWork();
WorkerThread->quit();
}
}

最初应用程序工作正常,但在按下按钮的一些操作来打开和关闭线程的工作后,出现以下错误......

QObject::killTimers(): 定时器不能从另一个线程停止

我对这个错误感到很困惑......我是否需要将启动/停止函数实现为信号和插槽而不是类的成员函数?

最佳答案

不启停WorkerThread .让它继续运行。另外,移动您的StartWork()StopWork()公共(public)插槽部分的方法。你真的根本不需要互斥锁。

worker .h

class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = 0);

signal:
void SignalToObj_mainThreadGUI();
void running();
void stopped();

public slots:
void StopWork();
void StartWork();

private slots:
void do_Work();

private:
volatile bool running,stopped;
};

worker .cpp
worker::worker(QObject *parent) :
QObject(parent), stopped(false), running(false)
{}

void worker::do_Work()
{
emit SignalToObj_mainThreadGUI();

if ( !running || stopped ) return;

// do important work here

// allow the thread's event loop to process other events before doing more "work"
// for instance, your start/stop signals from the MainWindow
QMetaObject::invokeMethod( this, "do_Work", Qt::QueuedConnection );
}

void worker::StopWork()
{
stopped = true;
running = false;
emit stopped();
}

void worker::StartWork()
{
stopped = false;
running = true;
emit running();
do_Work();
}

主窗口.h
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();

signals:
void startWork();
void stopWork();

private slots:
void on_pushButton_push_to_start_clicked();
void on_pushButton_push_to_stop_clicked();

private:
Ui::MainWindow *ui;
worker *myWorker;
QThread *WorkerThread;

};

主窗口.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

myWorker = new worker;
WorkerThread = new QThread;
myWorker.moveToThread(WorkerThread);

connect( this, SIGNAL(startWork()), myWorker, SLOT(StartWork()) );
connect( this, SIGNAL(stopWork()), myWorker, SLOT(StopWork()) );
}

void MainWindow::on_pushButton_push_to_start_clicked()
{
emit startWork();
}

void MainWindow::on_pushButton_push_to_stop_clicked()
{
emit stopWork();
}

关于multithreading - 如何实现线程的频繁启动/停止(QThread),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14051276/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com