QT多线程怎样设置任务执行的优先级

时间:2022-06-15 08:04:38
     先看主要代码:
1.WriteObject类继承自QObject
class WriteObject : public QObject
{
    Q_OBJECT

public:
    /*
    功能 :构造函数
    参数:无
    返回值:无
    */
    WriteObject(QObject *parent=0);
    ~WriteObject ();

signals:
    void haveFinished();

public slots:
    void run(const QString& cnt);
};


WriteObject::WriteObject (QObject *parent)
: QObject(parent)
{

}

/*
功能 :析构函数
参数:无
返回值:无
*/
WriteObject::~WriteObject ()
{
}

/*
功能 :运行
参数:无
返回值:无
*/
void WriteObject::run(const QString& cnt)
{
    QString dd = cnt + ": thread locked";
    qDebug() << dd;

    Sleep(10000);

    dd = cnt + ": thread finish";
    qDebug() << dd;
    return;
}

2.窗口类MainWindow继承QMainWindow
class MainWindow : public QMainWindow
{
    Q_OBJECT

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

signals:
    void haveClicked(const QString&);

private slots:
    void on_start_clicked();
    void on_insert_clicked();

private:
    Ui::MainWindow *ui;
    int k;
    QThread t;
    WriteObject *writeDataObiect;
};


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    k(0)
{
    ui->setupUi(this);
    writeDataObiect = new WriteObject();
    writeDataObiect->moveToThread(&t);
    connect(this, SIGNAL(haveClicked(const QString&)), writeDataObiect, SLOT(run(const QString&)));
    t.start();
}

MainWindow::~MainWindow()
{
    delete ui;

    if(writeDataObiect )
    {
        delete writeDataObiect;
        writeDataObiect = NULL;
    }
}

void MainWindow::on_start_clicked()
{
    k++;
    QString str = QString::number(k);
    emit haveClicked(str);
}

void MainWindow::on_insert_clicked()
{
    QString str = "insert";
    emit haveClicked(str);
}

         在界面上放了个start和insert按钮,每按一次start按钮就会运行on_start_clicked()函数,k会加1,并把该参数传入到新建的WriteObject对象(通过moveToThread放到线程t对象中),然后运行WriteObject的槽函数run();而insert按钮对应on_insert_clicked()函数。
          我的目的是单击多次(如3次)start按钮,然后立马单击insert按钮,怎样可以时insert按钮响应优先处理?
         实际的测试结果是:我快速连续单击三次start按钮,然后马上单击insert按钮,生成的日志文件如下:
2015-07-22 10:46:41):"1: thread locked"
(2015-07-22 10:46:51):"1: thread finish"
(2015-07-22 10:46:51):"2: thread locked"
(2015-07-22 10:47:01):"2: thread finish"
(2015-07-22 10:47:01):"3: thread locked"
(2015-07-22 10:47:11):"3: thread finish"
(2015-07-22 10:47:11):"insert: thread locked"
(2015-07-22 10:47:21):"insert: thread finish"

         而我希望的结果是:
2015-07-22 10:46:41):"1: thread locked"
(2015-07-22 10:46:51):"1: thread finish"
(2015-07-22 10:46:51):"insert: thread locked"
(2015-07-22 10:47:01):"insert: thread finish"

(2015-07-22 10:47:01):"2: thread locked"
(2015-07-22 10:47:11):"2: thread finish"
(2015-07-22 10:47:11):"3: thread locked"
(2015-07-22 10:47:21):"3: thread finish"
         由于单击insert按钮时,第一次单击start按钮的事件应该已经在线程中处理,所以希望insert按钮事件可以紧随其后执行,请问要怎样设置这些事件的优先级?

7 个解决方案

#1


代码太多懒得看,线程同步的问题就用QWaitCondition,1号线程开始的时候就让2号线程wait,等1号执行完了再让2号wake

#2


queue方式的信号槽是通过 postEvent()来实现的。

如果你要充分利用事件的优先级的话,queue方式的信号槽就不行了,不过你可以直接使用postEvent来做。

void QCoreApplication::postEvent(QObject * receiver, QEvent * event, int priority = Qt::NormalEventPriority)

#3


引用 楼主 ljhlwy2010 的回复:
     先看主要代码:
1.WriteObject类继承自QObject
class WriteObject : public QObject
{
    Q_OBJECT

public:
    /*
    功能 :构造函数
    参数:无
    返回值:无
    */
    WriteObject(QObject *parent=0);
    ~WriteObject ();

signals:
    void haveFinished();

public slots:
    void run(const QString& cnt);
};


WriteObject::WriteObject (QObject *parent)
: QObject(parent)
{

}

/*
功能 :析构函数
参数:无
返回值:无
*/
WriteObject::~WriteObject ()
{
}

/*
功能 :运行
参数:无
返回值:无
*/
void WriteObject::run(const QString& cnt)
{
    QString dd = cnt + ": thread locked";
    qDebug() << dd;

    Sleep(10000);

    dd = cnt + ": thread finish";
    qDebug() << dd;
    return;
}

2.窗口类MainWindow继承QMainWindow
class MainWindow : public QMainWindow
{
    Q_OBJECT

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

signals:
    void haveClicked(const QString&);

private slots:
    void on_start_clicked();
    void on_insert_clicked();

private:
    Ui::MainWindow *ui;
    int k;
    QThread t;
    WriteObject *writeDataObiect;
};


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    k(0)
{
    ui->setupUi(this);
    writeDataObiect = new WriteObject();
    writeDataObiect->moveToThread(&t);
    connect(this, SIGNAL(haveClicked(const QString&)), writeDataObiect, SLOT(run(const QString&)));
    t.start();
}

MainWindow::~MainWindow()
{
    delete ui;

    if(writeDataObiect )
    {
        delete writeDataObiect;
        writeDataObiect = NULL;
    }
}

void MainWindow::on_start_clicked()
{
    k++;
    QString str = QString::number(k);
    emit haveClicked(str);
}

void MainWindow::on_insert_clicked()
{
    QString str = "insert";
    emit haveClicked(str);
}

         在界面上放了个start和insert按钮,每按一次start按钮就会运行on_start_clicked()函数,k会加1,并把该参数传入到新建的WriteObject对象(通过moveToThread放到线程t对象中),然后运行WriteObject的槽函数run();而insert按钮对应on_insert_clicked()函数。
          我的目的是单击多次(如3次)start按钮,然后立马单击insert按钮,怎样可以时insert按钮响应优先处理?
         实际的测试结果是:我快速连续单击三次start按钮,然后马上单击insert按钮,生成的日志文件如下:
2015-07-22 10:46:41):"1: thread locked"
(2015-07-22 10:46:51):"1: thread finish"
(2015-07-22 10:46:51):"2: thread locked"
(2015-07-22 10:47:01):"2: thread finish"
(2015-07-22 10:47:01):"3: thread locked"
(2015-07-22 10:47:11):"3: thread finish"
(2015-07-22 10:47:11):"insert: thread locked"
(2015-07-22 10:47:21):"insert: thread finish"

         而我希望的结果是:
2015-07-22 10:46:41):"1: thread locked"
(2015-07-22 10:46:51):"1: thread finish"
(2015-07-22 10:46:51):"insert: thread locked"
(2015-07-22 10:47:01):"insert: thread finish"

(2015-07-22 10:47:01):"2: thread locked"
(2015-07-22 10:47:11):"2: thread finish"
(2015-07-22 10:47:11):"3: thread locked"
(2015-07-22 10:47:21):"3: thread finish"
         由于单击insert按钮时,第一次单击start按钮的事件应该已经在线程中处理,所以希望insert按钮事件可以紧随其后执行,请问要怎样设置这些事件的优先级?
我是想将任务改变执行顺序,比如有2个任务是轮询执行的,突然来个紧急的任务,需要将这个任务优先执行,而不是按顺序先执行前面的任务(假设前面的任务还在排队但还未执行),我用的是一个线程管理对象的方式,有什么好办法吗?

#4


引用 1 楼 yuyu414 的回复:
代码太多懒得看,线程同步的问题就用QWaitCondition,1号线程开始的时候就让2号线程wait,等1号执行完了再让2号wake
我是想将任务改变执行顺序,比如有2个任务是轮询执行的,突然来个紧急的任务,需要将这个任务优先执行,而不是按顺序先执行前面的任务(假设前面的任务还在排队但还未执行),我用的是一个线程管理对象的方式,有什么好办法吗?

#5


引用 2 楼 dbzhang800 的回复:
queue方式的信号槽是通过 postEvent()来实现的。

如果你要充分利用事件的优先级的话,queue方式的信号槽就不行了,不过你可以直接使用postEvent来做。

void QCoreApplication::postEvent(QObject * receiver, QEvent * event, int priority = Qt::NormalEventPriority)
请问是把每个任务设置成事件(Event)来做吗?愿闻其详,谢谢!

#6


优先级:void QThread::setPriority(Priority priority)

#7


引用 6 楼 yxred 的回复:
优先级:void QThread::setPriority(Priority priority)
这个是线程优先级的设置,可是我用的是一个线程管理对象的方法,就是说用一个线程处理多个事件,用线程的优先级是不行的,不过还是谢谢你。

#1


代码太多懒得看,线程同步的问题就用QWaitCondition,1号线程开始的时候就让2号线程wait,等1号执行完了再让2号wake

#2


queue方式的信号槽是通过 postEvent()来实现的。

如果你要充分利用事件的优先级的话,queue方式的信号槽就不行了,不过你可以直接使用postEvent来做。

void QCoreApplication::postEvent(QObject * receiver, QEvent * event, int priority = Qt::NormalEventPriority)

#3


引用 楼主 ljhlwy2010 的回复:
     先看主要代码:
1.WriteObject类继承自QObject
class WriteObject : public QObject
{
    Q_OBJECT

public:
    /*
    功能 :构造函数
    参数:无
    返回值:无
    */
    WriteObject(QObject *parent=0);
    ~WriteObject ();

signals:
    void haveFinished();

public slots:
    void run(const QString& cnt);
};


WriteObject::WriteObject (QObject *parent)
: QObject(parent)
{

}

/*
功能 :析构函数
参数:无
返回值:无
*/
WriteObject::~WriteObject ()
{
}

/*
功能 :运行
参数:无
返回值:无
*/
void WriteObject::run(const QString& cnt)
{
    QString dd = cnt + ": thread locked";
    qDebug() << dd;

    Sleep(10000);

    dd = cnt + ": thread finish";
    qDebug() << dd;
    return;
}

2.窗口类MainWindow继承QMainWindow
class MainWindow : public QMainWindow
{
    Q_OBJECT

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

signals:
    void haveClicked(const QString&);

private slots:
    void on_start_clicked();
    void on_insert_clicked();

private:
    Ui::MainWindow *ui;
    int k;
    QThread t;
    WriteObject *writeDataObiect;
};


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    k(0)
{
    ui->setupUi(this);
    writeDataObiect = new WriteObject();
    writeDataObiect->moveToThread(&t);
    connect(this, SIGNAL(haveClicked(const QString&)), writeDataObiect, SLOT(run(const QString&)));
    t.start();
}

MainWindow::~MainWindow()
{
    delete ui;

    if(writeDataObiect )
    {
        delete writeDataObiect;
        writeDataObiect = NULL;
    }
}

void MainWindow::on_start_clicked()
{
    k++;
    QString str = QString::number(k);
    emit haveClicked(str);
}

void MainWindow::on_insert_clicked()
{
    QString str = "insert";
    emit haveClicked(str);
}

         在界面上放了个start和insert按钮,每按一次start按钮就会运行on_start_clicked()函数,k会加1,并把该参数传入到新建的WriteObject对象(通过moveToThread放到线程t对象中),然后运行WriteObject的槽函数run();而insert按钮对应on_insert_clicked()函数。
          我的目的是单击多次(如3次)start按钮,然后立马单击insert按钮,怎样可以时insert按钮响应优先处理?
         实际的测试结果是:我快速连续单击三次start按钮,然后马上单击insert按钮,生成的日志文件如下:
2015-07-22 10:46:41):"1: thread locked"
(2015-07-22 10:46:51):"1: thread finish"
(2015-07-22 10:46:51):"2: thread locked"
(2015-07-22 10:47:01):"2: thread finish"
(2015-07-22 10:47:01):"3: thread locked"
(2015-07-22 10:47:11):"3: thread finish"
(2015-07-22 10:47:11):"insert: thread locked"
(2015-07-22 10:47:21):"insert: thread finish"

         而我希望的结果是:
2015-07-22 10:46:41):"1: thread locked"
(2015-07-22 10:46:51):"1: thread finish"
(2015-07-22 10:46:51):"insert: thread locked"
(2015-07-22 10:47:01):"insert: thread finish"

(2015-07-22 10:47:01):"2: thread locked"
(2015-07-22 10:47:11):"2: thread finish"
(2015-07-22 10:47:11):"3: thread locked"
(2015-07-22 10:47:21):"3: thread finish"
         由于单击insert按钮时,第一次单击start按钮的事件应该已经在线程中处理,所以希望insert按钮事件可以紧随其后执行,请问要怎样设置这些事件的优先级?
我是想将任务改变执行顺序,比如有2个任务是轮询执行的,突然来个紧急的任务,需要将这个任务优先执行,而不是按顺序先执行前面的任务(假设前面的任务还在排队但还未执行),我用的是一个线程管理对象的方式,有什么好办法吗?

#4


引用 1 楼 yuyu414 的回复:
代码太多懒得看,线程同步的问题就用QWaitCondition,1号线程开始的时候就让2号线程wait,等1号执行完了再让2号wake
我是想将任务改变执行顺序,比如有2个任务是轮询执行的,突然来个紧急的任务,需要将这个任务优先执行,而不是按顺序先执行前面的任务(假设前面的任务还在排队但还未执行),我用的是一个线程管理对象的方式,有什么好办法吗?

#5


引用 2 楼 dbzhang800 的回复:
queue方式的信号槽是通过 postEvent()来实现的。

如果你要充分利用事件的优先级的话,queue方式的信号槽就不行了,不过你可以直接使用postEvent来做。

void QCoreApplication::postEvent(QObject * receiver, QEvent * event, int priority = Qt::NormalEventPriority)
请问是把每个任务设置成事件(Event)来做吗?愿闻其详,谢谢!

#6


优先级:void QThread::setPriority(Priority priority)

#7


引用 6 楼 yxred 的回复:
优先级:void QThread::setPriority(Priority priority)
这个是线程优先级的设置,可是我用的是一个线程管理对象的方法,就是说用一个线程处理多个事件,用线程的优先级是不行的,不过还是谢谢你。