赞
踩
知识点:启动进程 ,线程 ,线程同步互斥
应用场景:通常在qt中打开另一个程序
process模板
- QString program = “/bin/ls";
- QStringList arguments;
- arguments << "-l" << “-a";
-
- QProcess *myProcess = new QProcess(parent);
- myProcess->execute(program, arguments);
示例:
widget.h
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include <QWidget>
- #include <QLineEdit>
- #include <QPushButton>
- #include <QFileDialog>
- #include <QProcess>
- #include <QStringList>
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- Widget(QWidget *parent = 0);
- ~Widget();
- public slots:
- void showfile()
- {
- QString filename = QFileDialog::getOpenFileName();
- le->setText(filename);
-
- QStringList arg = {filename};
- QProcess ppp;
- ppp.execute("notepad", arg);
- }
-
- private:
- QLineEdit *le;
- QPushButton *pb;
- };
-
- #endif // WIDGET_H

widget.cpp
- #include "widget.h"
- #include <QVBoxLayout>
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- {
- le = new QLineEdit;
- pb = new QPushButton("showtxt");
-
- QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(le);
- vbox->addWidget(pb);
- setLayout(vbox);
-
- connect(pb, SIGNAL(clicked(bool)), this, SLOT(showfile()));
- }
-
- Widget::~Widget()
- {
-
- }

效果在qt中使用文本编辑器打开一个文本。
应用场景:启动一个线程和进程来辅助程序
线程:
- class WorkerThread : public Qthread{
- Q_OBJECT
- void run() {
- /* ... here is the expensive or blocking operation ... */
- emit resultReady(result);
- }
- signals:
- void resultReady(const QString &s);
- };
- WorkerThread x;
- x.start();
void run()
方法:这是QThread
的一个虚函数,你需要在子类中重写它以实现线程的任务。当调用线程的start()
方法时,这里的代码将在新的线程中执行。
void resultReady(const QString &s)
信号:这是一个自定义信号,当线程完成工作并有结果可供返回时,将通过emit
关键字发射这个信号。
QT是信号驱动、或者异步驱动的框架,平时app需要执行到a.exec()才会执行
双线程示例:一个线程打印数组,一个线程排序数组
thread_show.h(继承QThread类)
- #ifndef THREAD_SHOW_H
- #define THREAD_SHOW_H
-
- #include <Qthread>
- #include <QDebug>
- #include <QMutex>
-
- class thread_show : public QThread
- {
- Q_OBJECT
- public:
- thread_show(char *p):m_arr(p){}
-
- void run() //这是QThread的一个虚函数(qt中斜线表示),你需要在子类中重写它以实现线程的任务。当调用线程的start()方法时,这里的代码将在新的线程中执行。
- {
- while(1)
- {
- //lock
- qDebug()<<m_arr;
- sleep(1);
- }
-
- }
- private:
- char *m_arr;
-
- };
-
- #endif // THREAD_SHOW_H

thread_show.cpp(重写构造函数)
- #include "thread_show.h"
-
- /*
- thread_show::thread_show()
- {
- }
- */
thread_rev.h
- #ifndef THREAD_REV_H
- #define THREAD_REV_H
-
- #include <QThread>
-
- class thread_rev : public QThread
- {
- Q_OBJECT
- public:
- thread_rev(char *p):m_arr(p){} //构造时,直接赋值效率高
-
- void run()
- {
- while(1)
- {
- for(int i=0; i<5; i++)
- {
- m_arr[i] ^= m_arr[9-i];
- m_arr[9-i] ^= m_arr[i];
- m_arr[i] ^= m_arr[9-i];
- }
- }
- }
- private:
- char *m_arr;
- };
-
- #endif // THREAD_REV_H

thread_rev.cpp(重写构造函数)
- #include "thread_rev.h"
-
- /*
- thread_rev::thread_rev()
- {
- }
- */
main.cpp
- #include "widget.h"
- #include <QApplication>
- #include "thread_rev.h"
- #include "thread_show.h"
-
-
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
-
- char arr[] = "0123456789";
-
- thread_show t1(arr); //打印
- thread_rev t2(arr); //翻转数组
-
- t1.start();
- t2.start();
-
- return a.exec();
- }

效果:两个线程同时操作,打印出来的数组无规律
官方示例
- QSemaphore :
- QSemaphore sem(5); // sem.available() == 5
- sem.acquire(3); // sem.available() == 2
- sem.acquire(2); // sem.available() == 0
- sem.release(5); // sem.available() == 5
- sem.release(5); // sem.available() == 10
- sem.tryAcquire(1); // sem.available() == 9, returns true
- sem.tryAcquire(250); // sem.available() == 9, returns false
-
- QMutex ://locker
- QMutex mutex;
- void method1(){
- mutex.lock();
- mutex.unlock();
- }
- void method2(){
- mutex.lock();
- mutex.unlock();
- }

实验示例:
thread_show.h
- #ifndef THREAD_SHOW_H
- #define THREAD_SHOW_H
-
- #include <Qthread>
- #include <QDebug>
- #include <QMutex>
-
- class thread_show : public QThread
- {
- Q_OBJECT
- public:
- thread_show(char *p, QMutex *l):m_arr(p), m_arrlock(l){}
-
- void run() //这是QThread的一个虚函数(qt中斜线表示),你需要在子类中重写它以实现线程的任务。当调用线程的start()方法时,这里的代码将在新的线程中执行。
- {
- while(1)
- {
-
- m_arrlock->lock();
- qDebug()<<m_arr;
- m_arrlock->unlock();
- sleep(1);
- }
-
- }
- private:
- char *m_arr;
- QMutex *m_arrlock;
-
- };
-
- #endif // THREAD_SHOW_H

thread_show.cpp
- #include "thread_show.h"
-
- /*
- thread_show::thread_show()
- {
- }
- */
thread_rev.h
- #ifndef THREAD_REV_H
- #define THREAD_REV_H
-
- #include <QThread>
- #include <QMutex>
-
- class thread_rev : public QThread
- {
- Q_OBJECT
- public:
- thread_rev(char *p, QMutex *l):m_arr(p), m_arrlock(l){}
-
- void run()
- {
- while(1)
- {
- m_arrlock->lock();
- for(int i=0; i<5; i++)
- {
- m_arr[i] ^= m_arr[9-i];
- m_arr[9-i] ^= m_arr[i];
- m_arr[i] ^= m_arr[9-i];
- }
- m_arrlock->unlock();
- }
- }
- private:
- char *m_arr;
- QMutex *m_arrlock;
-
- };
-
- #endif // THREAD_REV_H

thread_rev.cpp
- #include "thread_rev.h"
-
- /*
- thread_rev::thread_rev()
- {
- }
- */
main.cpp
- #include "widget.h"
- #include <QApplication>
- #include "thread_rev.h"
- #include "thread_show.h"
- #include <QMutex>
-
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
-
- char arr[] = "0123456789";
- QMutex arr_lock;
-
- thread_show t1(arr,&arr_lock); //打印
- thread_rev t2(arr,&arr_lock); //翻转数组
-
- t1.start();
- t2.start();
-
- return a.exec();
- }

效果:两个线程同时操作,打印出来的数组均为排序后的结果,排序中不会受到干扰
目的:实现一个线程获取资源需要等另一个线程释放资源。
thread_hello.h
- #ifndef THREAD_HELLO_H
- #define THREAD_HELLO_H
-
- #include <QSemaphore>
- #include <QThread>
- #include <QDebug>
-
- class thread_hello : public QThread
- {
- Q_OBJECT
- public:
- thread_hello(QSemaphore *s):sem(s){ }
-
- void run()
- {
- while(1)
- {
- qDebug()<<"hello";
- sleep(1);
-
- //V
- sem->release();
- }
-
- }
- private:
- QSemaphore *sem;
- };
-
- #endif // THREAD_HELLO_H

thread_hello.cpp
- #include "thread_hello.h"
-
- /*
- thread_hello::thread_hello()
- {
- }
- */
thread_world.h
- #ifndef THREAD_WORLD_H
- #define THREAD_WORLD_H
-
- #include <QThread>
- #include <QDebug>
- #include <QSemaphore>
-
- class thread_world : public QThread
- {
- Q_OBJECT
- public:
- thread_world(QSemaphore *s):sem(s){ }
-
- void run() //字体歪的就是虚函数
- {
- while(1)
- {
- //P
- sem->acquire();
- qDebug()<<"world";
- }
-
- }
- private:
- QSemaphore *sem;
- };
-
- #endif // THREAD_WORLD_H

thread_world.cpp
- #include "thread_hello.h"
-
- /*
- thread_hello::thread_hello()
- {
- }
- */
main.cpp
- #include <QCoreApplication>
- #include "thread_hello.h"
- #include "thread_world.h"
- #include <QSemaphore>
-
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv);
-
- QSemaphore sem;
- thread_hello hello(&sem);
- thread_world world(&sem);
-
- hello.start();
- world.start();
-
- return a.exec();
- }

效果,hello先打印,才会有world。
综合示例:实现两个进度条在下载
mythread1.h
- #ifndef MYTHREAD1_H
- #define MYTHREAD1_H
-
- #include <QThread>
-
- class myThread1 : public QThread
- {
- Q_OBJECT
- signals:
- downloaded(int);
- public:
- myThread1();
-
- void run()
- {
- for(int i=0;i<100; i++)
- {
- //p1->setValue(i);
- emit downloaded(i);
- QThread::sleep(2);
- }
- }
- };
-
- #endif // MYTHREAD1_H

mythread1.cpp
- #include "mythread1.h"
-
- myThread1::myThread1()
- {
-
- }
mythread2.h
- #ifndef MYTHREAD2_H
- #define MYTHREAD2_H
-
- #include <QThread>
-
- class myThread2 : public QThread
- {
- Q_OBJECT
- signals:
- downloaded(int);
- public:
- myThread2();
-
- void run()
- {
- for(int i=0;i<100; i++)
- {
- //p1->setValue(i);
- emit downloaded(i);
- QThread::sleep(1);
- }
- }
- };
-
- #endif // MYTHREAD2_H

mythread1.cpp
- #include "mythread2.h"
-
- myThread2::myThread2()
- {
-
- }
widget.h
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include <QWidget>
- #include <QProgressBar>
- #include "mythread2.h"
- #include "mythread1.h"
-
-
- class Widget : public QWidget
- {
- Q_OBJECT
-
- public:
- Widget(QWidget *parent = 0);
- ~Widget();
- private:
- QProgressBar *p1, *p2;
-
- myThread1 *t1;
- myThread2 *t2;
- };
-
- #endif // WIDGET_H

widget.cpp
- #include "widget.h"
- #include <QVBoxLayout>
- #include <QThread>
-
-
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- {
- p1 = new QProgressBar;
- p2 = new QProgressBar;
-
- QVBoxLayout *vbox = new QVBoxLayout;
- vbox->addWidget(p1);
- vbox->addWidget(p2);
- setLayout(vbox);
-
- t1 = new myThread1;
- t2 = new myThread2;
- connect(t1, SIGNAL(downloaded(int)), p1, SLOT(setValue(int)));
- connect(t2, SIGNAL(downloaded(int)), p2, SLOT(setValue(int)));
- t1->start();
- t2->start();
-
- #if 0
- for(int i=0;i<100; i++)
- {
- p1->setValue(i);
- QThread::sleep(1);
- }
-
- for(int i=0;i<100; i++)
- {
- p2->setValue(i);
- QThread::sleep(2);
- }
- #endif
- }
-
- Widget::~Widget()
- {
-
- }

注:
downloaded(不需要实现,qt实现的不是函数)
emit发送一个信号
exit 发送信号
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。