Qt进程间通信及内存共享,信号量,锁机制,线程同步

1、进程与线程的基础知识
2、qt进程通信的共享内存
概念:共享内存指 (shared memory)在多处理器的计算机系统中,可以被不同中央处理器(CPU)访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是Unix下的多进程之间的通信方法 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。
类方法:

//.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include
#include
#include

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void loadfrommem();
void loadfromfile();

private slots:
void on_pushButton_mem_clicked();

private:
Ui::MainWindow *ui;
QSharedMemory shareMemory;
};

#endif // MAINWINDOW_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//.cpp
#include “mainwindow.h”
#include “ui_mainwindow.h”
#include
#include
#include
#include
#include
#include

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
shareMemory.setKey(“share”);
connect(ui->pushButton_mem,QPushButton::clicked,this,MainWindow::loadfrommem);
connect(ui->pushButton_file,QPushButton::clicked,this,MainWindow::loadfromfile);

}

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

void MainWindow::loadfromfile()
{

if(shareMemory.isAttached())
{
    shareMemory.detach();//将该进程与共享内存分离
}
QString filename=QFileDialog::getOpenFileName(this);
QPixmap pixmap;
pixmap.load(filename);//从文件中找到图片

QBuffer buffer;//建立缓存对象
QDataStream out(&buffer);//数据流操作,用于操作缓存的数据
buffer.open(QBuffer::ReadWrite);//打开qbuffer的读写权限
out<<pixmap;//输出piamap
qDebug()<<buffer.size();

int size=buffer.size();
if(!shareMemory.create(size))
{
     qDebug()<<tr("can not creat memory sqgment");
      qDebug()<<shareMemory.error();
      return;
}
qDebug()<<shareMemory.size();

//
//共享内存部分上锁,使用内存段
shareMemory.lock();
char to=(char)shareMemory.data();
const charfrom=(char)buffer.data().data();
memcpy(to,from,qMin(size,shareMemory.size()));//数据从该进程中拷贝到共享数据内存中
shareMemory.unlock();
/
/
}

void MainWindow::loadfrommem()
{
if(!shareMemory.attach())
{
qDebug()<<tr(“can not creat memory sqgment”);

}
QBuffer buffer;
QDataStream in(&buffer);
QPixmap pixmap;
//
shareMemory.lock();
buffer.setData((char*)shareMemory.constData(),shareMemory.size());//将sharememory里面的数据放到buffer之中
buffer.open(QBuffer::ReadWrite);
in>>pixmap;
shareMemory.unlock();
shareMemory.detach();//将sharememeory与该进程分离
ui->label->setPixmap(pixmap);
/
/
}
扩展findChildren的用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//扩展findChildren的用法
//主线程
void MainWindow::buttonclicked()
{
// QToolButton* btns = this->findChild<QToolButton*>(QString(“btn%1”).arg(i));
QList<QToolButton*> btns=this->findChildren<QToolButton*>();

qDebug()<<btns;
foreach (QToolButton*btn, btns) {
    connect(btn,&QToolButton::clicked,measureThread,&MeasureThread::setTwoRelay);
}

}

//子线程
void MeasureThread::setTwoRelay()
{
QToolButton btn=(QToolButton)sender();
QString puttonName=btn->objectName();
QStringList puttonlist = puttonName.split("_");
realayNameBegin=puttonlist.at(1);
realayNameEnd=puttonlist.at(2);
SwitchRelay();

//    QStringList list;
//    QVector<int> v;
//    for(int i=1;i<25;i++)
//    {
//        v.push_back(i);
//    }
//    for(int i=0;i<v.size();i++)
//    {
//       int x=v[i];
//       QString temp=QString::number(x);
//       list.append(temp);

//    }

}
3、线程同步
线程同步典型例子“生产者-消费者模型”,也称有限缓冲问题
qt解决线程同步三个方法

(1)、信号量
使用类:QSemaphore
概念:pv操作,加减

(2)、进程类/锁机制
QMutex/QMutexLocker
QWaitCondtion
多线程使用的锁机制
MutexOnly
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifndef MUTEXONLY_H
#define MUTEXONLY_H

#include
#include
#include
#include
#include
#include

using namespace std;
class MutexOnly
{
public:
// MutexOnly();
//预计生产(或消费)数量
int loopCount;
//当前产品数量
int product;
//仓库能容纳最大产品数量
int capacity;

QMutex mutex;


//QWaitCondition类为线程同步提供了一个条件变量,此处设置条件

QWaitCondition productIsNotFull;//商店产品不是满的
QWaitCondition productIsNotEmpty;//商店产品不为空

//生产者**********************************************************************************

class Producer:public QThread
{
public:
    Producer(MutexOnly *manager) : QThread() {
        this->manager=manager;

}
protected:
    void run(){
        for(int i=0;i<manager->loopCount;i++)
        {
            manager->mutex.lock();
            while(manager->product==manager->capacity)
            {
                //释放该锁,并且阻塞当前线程,直到条件满足(即调用wake方法被唤醒)
                manager->productIsNotFull.wait(&manager->mutex);
            }
            manager->product++;
            cout<<i<<".P"<<manager->product<<", ";
            manager->productIsNotEmpty.wakeAll();
            manager->mutex.unlock();
        }
    }
private:
    MutexOnly *manager;
};




/****消费者************************************************************************/

class Consumer:public QThread{

public:
    Consumer(MutexOnly *manager):QThread(){

        this->manager=manager;

    }

protected:
    void run(){
        for(int i; i<manager->loopCount;i++)
        {
            manager->mutex.lock();
            while(manager->product==0){
                manager->productIsNotEmpty.wait(&manager->mutex);
            }
            manager->product--;
            cout<<i<<",C="<<manager->product<<", ";
            manager->productIsNotFull.wakeAll();
            manager->mutex.unlock();
        }

    }

private:
    MutexOnly *manager;
};

 /****无修饰方法************************************************************************/

public:
void test(int loopCount,int capacity)
{
this->loopCount=loopCount;
this->capacity=capacity;
this->product=0;

    Producer producer(this);
    Consumer consumer(this);
    //thread.start会调用thread内部的run方法
    producer.start();
    consumer.start();



    //接下来阻塞该线程直到所有条件都满足
    producer.wait();
    consumer.wait();
    cout<<endl;

}

};

#endif // MUTEXONLY_H
MutexWaitCondition

#ifndef MUTEXWAITCONDITION_H
#define MUTEXWAITCONDITION_H

#include
#include
#include
#include
#include
#include

using namespace std;

class MutexWaitCondition
{
public:
MutexWaitCondition();

public :
//预计生产(或消费)数量
int loopCount;
//当前产品数量
int product;
//仓库能容纳最大产品数量
int capacity;

QMutex mutex;


//QWaitCondition类为线程同步提供了一个条件变量,此处设置条件

QWaitCondition productIsNotFull;//商店产品不是满的
QWaitCondition productIsNotEmpty;//商店产品不为空

/*生产者**********************************************************************************/
class Producer:public QThread
{
public:
    Producer(MutexWaitCondition *manager) : QThread() {
        this->manager=manager;

}
protected:
    void run(){
        for(int i=0;i<manager->loopCount;i++)
        {
            manager->mutex.lock();
            while(manager->product==manager->capacity)
            {
                //释放该锁,并且阻塞当前线程,直到条件满足(即调用wake方法被唤醒)
                manager->productIsNotFull.wait(&manager->mutex);
            }
            manager->product++;
            cout<<i<<".P"<<manager->product<<", ";
            manager->productIsNotEmpty.wakeAll();
            manager->mutex.unlock();
        }
    }
private:
    MutexWaitCondition *manager;
};




/****消费者************************************************************************/


class Consumer:public QThread{

public:
    Consumer(MutexWaitCondition *manager):QThread(){

        this->manager=manager;

    }

protected:
    void run(){
        for(int i; i<manager->loopCount;i++)
        {
            manager->mutex.lock();
            while(manager->product==0){
                manager->productIsNotEmpty.wait(&manager->mutex);
            }
            manager->product--;
            cout<<i<<",C="<<manager->product<<", ";
            manager->productIsNotFull.wakeAll();
            manager->mutex.unlock();
        }

    }

private:
    MutexWaitCondition *manager;
};
/****无修饰方法************************************************************************/

public:
void test(int loopCount,int capacity)
{
this->loopCount=loopCount;
this->capacity=capacity;
this->product=0;

   Producer producer(this);
   Consumer consumer(this);
   //thread.start会调用thread内部的run方法
   producer.start();
   consumer.start();



   //接下来阻塞该线程直到所有条件都满足
   producer.wait();
   consumer.wait();
   cout<<endl;

}

};

#endif // MUTEXWAITCONDITION_H

SenaphoreMutex

#ifndef SENAPHOREMUTEX_H
#define SENAPHOREMUTEX_H

#include
#include
#include
#include
#include
#include
#include
using namespace std;

class SenaphoreMutex
{
public:
SenaphoreMutex();
public:
//预计生产(或消费)数量
int loopCount;
//当前产品数量
int product;
//仓库能容纳最大产品数量
int capacity;

QMutex mutex;

//QSemaphore类提供一个通用的计数信号量,定义了两个信号量对象
QSemaphore *productSemhore;
QSemaphore *leftSpaceSemaphore;

/*生产者*(****************************************************************************************************************/

class  Producer : public QThread{
public:
    Producer(SenaphoreMutex *manager): QThread() {
        this->manager=manager;

    }

protected:
    void run()
    {
        for(int i=0; i<manager->loopCount; i++)
        {
            //尝试获取(减去)n个被信号量控制的资源,如果n大于可用资源数量,它就会阻塞直到有足够的资源为止
            manager->leftSpaceSemaphore->acquire();
            //之所以lock要在acquire后面是因为:如果消费者拿到了锁,那么又没有商品,会导致死锁
            manager->mutex.lock();
            manager->productSemhore->release();
            cout<<i<<".P"<<manager->productSemhore->available()<<",";
            manager->mutex.unlock();

        }
    }

private:
    SenaphoreMutex *manager;
};
\


/*消费者*********************************************************************************************************************/

class Consumer : public QThread
{
public:
    Consumer(SenaphoreMutex *manager) :QThread(){

        this->manager=manager;


}
protected:
    void run(){
        for(int i=0; i<manager->loopCount;i++){
            manager->productSemhore->acquire();
            manager->mutex.lock();

            manager->leftSpaceSemaphore->release();
            cout<<i<<".C="<<manager->productSemhore->available()<<",";
            manager->mutex.unlock();


        }
    }
private:
    SenaphoreMutex *manager;
};



//无修饰的方法 默认是private的****************************************************************************/

public:
void test(int loopCount,int capacity)
{
this->loopCount=loopCount;
this->capacity=capacity;

    //参数为:信号量的当前值
    productSemhore=new  QSemaphore(0);
    leftSpaceSemaphore=new  QSemaphore(capacity);

    Producer producer(this);
    Consumer consumer(this);

    //thread.start   RUN
    producer.start();
    consumer.start();

    //阻塞该线程直到所有条件都满足
    producer.wait();

}

};

#endif // SENAPHOREMUTEX_H

#include
#include
#include
#include “mutexonly.h”
#include “mutexwaitcondition.h”
#include “senaphoremutex.h”

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
using namespace std;

int loopCount=100;
int capacity=3;
QTime time;

int mutexOnlyElapsed;
int mutexWaitConditonElapsed;
int SemaphoreMutexElapsed;

// cout<<“loopCount =”<<loopCount<<“capacity =”<<capacity<<endl<<endl;
// cout<<“MutexOnly”<<endl;

// MutexOnly mutexOnly;
// time.start();
// mutexOnly.test(loopCount,capacity);

// //milliseconds,返回最后一次调用start到现在已经经过的毫秒数
// mutexOnlyElapsed=time.elapsed();
// cout<<“elapsed:”<<mutexOnlyElapsed<<“ms”<<endl;
// cout<<endl;

cout<<"Mutexwaitcondition"<<endl;
MutexWaitCondition mutexWaitCondition;
time.restart();
mutexWaitConditonElapsed=time.elapsed();

cout<<"elapsed:"<<mutexWaitConditonElapsed<<"ms"<<endl;
cout<<endl;



cout<<'SemaphoreMutex'<<endl;
SenaphoreMutex SemaphoreMutex;
time.restart();
SemaphoreMutex.test(loopCount,capacity);
SemaphoreMutexElapsed=time.elapsed();
cout<<"elapsed"<<SemaphoreMutexElapsed<<"ms"<<endl;
cout<<endl;
return 0;




return a.exec();

}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值