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<
//
//共享内存部分上锁,使用内存段
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()<
}
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
QList
qDebug()<
}
//子线程
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 v;
// for(int i=1;i<25;i++)
// {
// v.push_back(i);
// }
// for(int i=0;i
}
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;iloopCount;i++)
{
manager->mutex.lock();
while(manager->product==manager->capacity)
{
//释放该锁,并且阻塞当前线程,直到条件满足(即调用wake方法被唤醒)
manager->productIsNotFull.wait(&manager->mutex);
}
manager->product++;
cout<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; iloopCount;i++)
{
manager->mutex.lock();
while(manager->product==0){
manager->productIsNotEmpty.wait(&manager->mutex);
}
manager->product--;
cout<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<
};
#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;iloopCount;i++)
{
manager->mutex.lock();
while(manager->product==manager->capacity)
{
//释放该锁,并且阻塞当前线程,直到条件满足(即调用wake方法被唤醒)
manager->productIsNotFull.wait(&manager->mutex);
}
manager->product++;
cout<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; iloopCount;i++)
{
manager->mutex.lock();
while(manager->product==0){
manager->productIsNotEmpty.wait(&manager->mutex);
}
manager->product--;
cout<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<
}
};
#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; iloopCount; i++)
{
//尝试获取(减去)n个被信号量控制的资源,如果n大于可用资源数量,它就会阻塞直到有足够的资源为止
manager->leftSpaceSemaphore->acquire();
//之所以lock要在acquire后面是因为:如果消费者拿到了锁,那么又没有商品,会导致死锁
manager->mutex.lock();
manager->productSemhore->release();
cout<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; iloopCount;i++){
manager->productSemhore->acquire();
manager->mutex.lock();
manager->leftSpaceSemaphore->release();
cout<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 =”< // MutexOnly mutexOnly; // //milliseconds,返回最后一次调用start到现在已经经过的毫秒数 }
// time.start();
// mutexOnly.test(loopCount,capacity);
// mutexOnlyElapsed=time.elapsed();
// cout<<“elapsed:”<cout<<"Mutexwaitcondition"<
你可能感兴趣的:(Qt进程间通信及内存共享,信号量,锁机制,线程同步)