QT之进程和线程

使用QT之进程和线程

共享内存

共享内存使用方法实例,在.ui中添加两个按钮控件,分别命名为:从文件中加载图片和从共享内存显示图片。并分别通过Label1和Label2显示出来。方法步骤:

(1)使用QFileDialog读取一幅图片,使用load加载到image中,在Label1中显示;
(2)创建buffer缓冲区,将image中的图片数据写入到buffer缓冲区中;
(3)在sharedMemory即共享内存中创建buffer大小的内存空间;
(4)调用sharedMemory的lock函数加锁,这是为了保证在同一时刻只有一个进程访问共享内存;
(5)通过memcpy函数将buffer中的图片数据复制到共享内存中;
(6)调用sharedMemory的unlock函数解锁;
(7)当点击 从文件中加载图片 按钮时,便在Label1中打开了图片并同时将图片存入到了共享内存中;之后我们通过共享内存直接读取图片;
(8)当点击 从共享内存显示图片 按钮时,使用buffer从共享内存中读取图片并在Label2中显示

void Dialog::loadFromFile()
{
    if(sharedMemory.isAttached()) detach();
    ui->label->setText(tr("选择一个图片"));
    QString filenames=QFileDialog::getOpenFileName(0,QString(),QString(),tr("images(*.png *.jpg)"));//读图片
    QImage image;
    image.load(filenames);//加载图片
    ui->label->setPixmap(QPixmap::fromImage(image));//标签显示图片
    QBuffer buffer;//建立缓冲区
    buffer.open(QBuffer::ReadWrite);//设置模式
    QDataStream out(&buffer);
    out<<image;//将图片写入缓冲区
    int size=buffer.size();//计算缓冲区大小
    sharedMemory.create(size);//在共享内存空间中创建相同大小的控件
    sharedMemory.lock();//锁操作
    char*to=(char *)sharedMemory.data();
    const char *from=buffer.data().data();
    memcpy(to,from,qMin(sharedMemory.size(),size));//将缓冲区内容复制到共享内存中
    sharedMemory.unlock();//解锁
}
void Dialog::loadFromMemory()
{
    QBuffer buffer;
    QDataStream in(&buffer);
    QImage image;

    sharedMemory.lock();
    buffer.setData((char*)sharedMemory.constData(),sharedMemory.size());
    buffer.open(QBuffer::ReadOnly);
    in>>image;
    sharedMemory.unlock();
    sharedMemory.detach();
    ui->label_2->setPixmap(QPixmap::fromImage(image));
}

void Dialog::detach()//将进程与共享内存分离
{
    if(!sharedMemory.detach())
        ui->label->setText(tr("无法从共享内存中分离"));
}

结果显示如图

QT之进程和线程_第1张图片

线程

设置两个按钮,一个用来启动进程,一个用来结束进程。
(1)在Mythread中声明stop函数和run函数,当启动thread的start函数时进入run函数(虚函数重写)默认为exec();
(2)调用stop()函数停止进程。
在Mythread.h中:

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include


class MyThread : public QThread
{
public:
    MyThread();
    void stop();
protected:
    void run();
private:
    volatile bool stopped;
};

#endif // MYTHREAD_H

在Mythread.cpp中:

#include "mythread.h"
#include<QDebug>

MyThread::MyThread()
{
    stopped=false;
}
void MyThread::run()
{
 qreal i=0;
 while(!stopped)
     qDebug()<<QString("in mythread: %1").arg(i++);
     stopped=false;


}
void MyThread::stop(){

    stopped=true;

}

QDialog.h中:

#ifndef DIALOG_H
#define DIALOG_H

#include 
#include"mythread.h"

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT

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

private:
    Ui::Dialog *ui;
    MyThread thread;
private slots:
    void on_startButton_clicked();
    void on_stopButton_clicked();
};

#endif // DIALOG_H

在QDialog.cpp中:

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

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

void Dialog::on_startButton_clicked()
{
    thread.start();
    ui->startButton->setEnabled(false);
    ui->stopButton->setEnabled(true);
}

void Dialog::on_stopButton_clicked()
{
    if(thread.isRunning()){
        thread.stop();

        ui->startButton->setEnabled(true);
        ui->stopButton->setEnabled(false);

    }
}

QT之进程和线程_第2张图片

同步线程

QT中的QMutex、QReadWriteLock、QSemaphore和QWaitCondition提供了同步线程的方法。
QMutex互斥锁,在同一时间至多有一个时间访问Mutex,当一个线程访问mutex时其锁住了线程将会进入睡眠直到mutex解锁。
QReadWriteLock允许同一时刻多个数据同时对数据进行读访问。
QSemaphore即信号量,时mutex的一般化,保证保护一定数量的同一资源,mutex只能保护一个资源;
QWaitContion即条件变量,允许一个线程在满足一定条件下唤醒其他线程。

信号量的生产者消费者问题

#ifndef SEM_H
#define SEM_H
#include
#include
#include
#include
const int DataSize=10;
const int BufferSize=5;
char buffer[BufferSize];
QSemaphore freeBytes(BufferSize);
QSemaphore usedBytes;
class producer:public QThread{
public:
    void run();
};
class consumer:public QThread{

public:
    void run();
};
void producer::run(){
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    for(int i=0;i"ACGT"[(int)qrand()%4];
        qDebug()<"producer: 51").arg(buffer[i%BufferSize]);
        usedBytes.release();
    }
}
void consumer::run(){
    for(int i=0;i"consumer: %1").arg(buffer[i%BufferSize]);
        freeBytes.release();
    }
}
#endif // SEM_H

你可能感兴趣的:(QT)