默默地EEer,原文地址:
http://www.cnblogs.com/hebaichuanyeah/p/5618781.html
在調用linux環境下線程API寫Cpp時,發現異常蛋疼,要么線程函數不能是類的成員函數,要么必須是類的static成員函數(意味着調用的成員變量也必須是static……其實還是不屬於類)。
Qt提供一套線程機制,只要繼承QThread基類並重新實現void run()函數即可。
新建thread.h繼承Qthread,並在thread.cpp中實現它。
thread.h
#include "QThread"
class Thread : public QThread
{
Q_OBJECT
public:
Thread();
// void setMessage(const Qstring &message);
void setRun();
void stop();
bool getState();
protected:
void run();
private:
// QString messageStr;
volatile bool enable;
signals:
void OutMessage(QString message);
};
thread.cpp,在run函數中循環1秒觸發一個信號輸出信息。
#include "thread.h"
Thread::Thread()
{
enable = true;
}
void Thread::run()
{
while(true)
{
if(enable)
{
this->OutMessage(tr("I'm run : thread 1"));
msleep(1000);
}
}
}
void Thread::stop()
{
enable = false;
}
void Thread::setRun()
{
enable = true;
}
bool Thread::getState()
{
return enable;
}
mainwindow.h,定義一些Qt控件
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QGridLayout>
#include <QPushButton>
#include <QTextEdit>
#include <QDoubleValidator>
#include <QComboBox>
#include <QTranslator>
#include "thread.h"
#define PI 3.14592653589
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
~MainWindow();
private:
QWidget* mainWindow;
QGridLayout * mainLayout;
QTextEdit * messageEdit;
QPushButton * clearButton;
QPushButton * runStopButton;
Thread * backThread;
private slots:
void updateMessage(QString message);
void clearMessage();
void runStopThread();
};
#endif
mainwindow.cpp
#include "mainwindow.h"
#include <QPainter>
MainWindow :: MainWindow()
{
mainWindow = new QWidget;
this->setCentralWidget(mainWindow);
backThread = new Thread();
backThread->start();
clearButton = new QPushButton(tr("clear"));
clearButton->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
runStopButton = new QPushButton(tr("stop"));
messageEdit = new QTextEdit();
messageEdit->setReadOnly(true);
mainLayout = new QGridLayout;
mainLayout->addWidget(messageEdit,0,0,5,5);
mainLayout->addWidget(clearButton,1,5,1,1);
mainLayout->addWidget(runStopButton,0,5,1,1);
mainWindow->setLayout(mainLayout);
QObject::connect(clearButton,SIGNAL(clicked()),this,SLOT(clearMessage()));
QObject::connect(runStopButton,SIGNAL(clicked()),this,SLOT(runStopThread()));
QObject::connect(backThread,SIGNAL(OutMessage(QString)),this,SLOT(updateMessage(QString)));
this->setWindowTitle(tr("thread test~"));
this->resize(QSize(300,100));
// this->setFixedSize(200,100);
}
MainWindow :: ~MainWindow()
{
mainWindow->deleteLater();
mainLayout->deleteLater();
messageEdit->deleteLater();
clearButton->deleteLater();
runStopButton->deleteLater();
}
void MainWindow::updateMessage(QString message)
{
messageEdit->append(message);
}
void MainWindow::clearMessage()
{
messageEdit->clear();
}
void MainWindow::runStopThread()
{
if(backThread->getState())
{
backThread->stop();
runStopButton->setText(tr("run"));
}
else
{
backThread->setRun();
runStopButton->setText(tr("stop"));
}
}
運行:

后台線程不斷打印信息,通過run/stop按鈕停止/啟動。
同時,Qt提供一套線程同步機制
QMutex(互斥鎖),QReadWriteLock(讀寫鎖),QSemaphore(信號量),QWaitCondition(阻塞等待一個條件)。
使用都很簡單,其中QWaitCondition,調用bool wait(QMutex *mutex, unsigned long time = ULONG_MAX)成員函數阻塞。 void wakeOne()和void wakeAll()喚醒一處和所有阻塞。(類似於C#里面的ManualResetEvent 類,.WaitOne() .Set())
