EA&UML日拱一卒-多任务编程超入门-(15)共享内存
前一个例子中说明的功能类似与程序之间对话的感觉,除了利用QProcess以外,由于操作系统,开发环境的不同,也有Socket通信,管道等方法,本连载就不一一赘述了。
本文说明另外一种方法,共享内存。开发环境依然是Windows环境中的QT。
被调用端代码
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <QSharedMemory>
#include <QSystemSemaphore>
#include <QByteArray>
void output(const char* msg)
{
QFile data("output.txt");
if (!data.open(QIODevice::WriteOnly
|QIODevice::Text
|QIODevice::Append)) {
return;
}
QTextStream out(&data);
out << msg << endl;
data.close();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
output("Server started!");
QSharedMemory buffer("SharedMemoryServer");
if(!buffer.create(1024))
{
output("QSharedMemory create failure!");
return -1;
}
QSystemSemaphore semDataOk("DataOK",
0,
QSystemSemaphore::Create);
QSystemSemaphore semBufferOk("BufferOK",
1,
QSystemSemaphore::Create);
while(true)
{
output("semDataOk.acquire();");
semDataOk.acquire();
output("semDataOk.acquire(),successed!");
QByteArray msg((char*)buffer.data());
output(msg.data());
semBufferOk.release();
if(msg == "bye")
{
break;
}
}
output("Server finished!");
return 0;
}
代码稍长,但并不复杂。慢慢看下来就好。
首先是一个向文件写入字符串的函数,只要知道功能就好。这个函数在main函数中会多次被调用,用于表明程序执行的进程。
接下来是main函数。
首先创建一个名为SharedMemoryServer的QSharedMemory对象。由于进程存在于不同的内存空间,所以共享的资源经常通过共同的名称来标识。
接 下来创建两个控制数据读写的QSystemSemaphore。和QSemaphore不同,QSystemSemaphore可以用于进程之间的同步。 和QSharedMemorySer一样,也通过名称来标识。两个QSystemSemaphore都使用 QSystemSemaphoe::create标志创建。
这两个QSystemSemaphore的使用方法和之前的文章【多任务编程超入门-(12)
关于Semaphore,一个不得不说的实例】相同,读者可以自行参照。
while循环中的处理也可以参照上述例子,等待数据准备好,从QSharedMemory中取出数据并写入文件中,然后设定缓冲区准备好QSystemSemaphore。
如果接收到的字符串是bye,则程序结束。
调用端代码
#include <QCoreApplication>
#include <QSharedMemory>
#include <QSystemSemaphore>
#include <QTextStream>
#include <QByteArray>
#include <QProcess>
#include <QThread>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QProcess server;
server.start("..\\..\\Server\\bin\\debug\\Server.exe"
,QStringList());
if (!server.waitForStarted())
return false;
QByteArray msg;
QTextStream cin(stdin);
QTextStream cout(stdout);
cout << "Input message to Server,bye to finish!" << endl;
QSharedMemory buffer("SharedMemoryServer");
while(!buffer.attach())
{
QThread::currentThread()->sleep(1);
cout << "QShareMemory attaching!" << endl;
}
cout << "QShareMemory attach OK!" << endl;
QSystemSemaphore semDataOk("DataOK");
QSystemSemaphore semBufferOk("BufferOK", 1);
while(msg != "bye")
{
cin >> msg;
semBufferOk.acquire();
strcpy((char*)buffer.data(), msg.constData());
semDataOk.release();
}
cout << "Waiting for server finish!" << endl;
if (!server.waitForFinished())
return -1;
cout << "Server finished!" << endl;
return 0;
}
首先是准备工作,也是最重要的一部分。
QProcess启动Server进程。这个步骤和之前说明的一样,不再说明。
接下来是定义QShareMemory对象,并调用attach方法,注意不是create方法。表明使用的是在其他进程中创建的相同名称的共享内存而不是重新创建。有进程之间执行时间的关系,可能需要等待一下。
接下来创建两个QSystemSemephore,和QSharedMemory同样,使用的是Server进程创建的对象,因此没有使用QSystemSemaphore::create标志。
while循环中比较简单,从键盘读入字符串,等待semBufferOK准备好,向缓冲区写入字符串,最后设定semDataOK。
执行结果
首先是调用端的输出,本例中输入了3个字符串,first,second和bye。
接下来被调用端的输出文件。红色的文字是从Client进程接受到的字符串。
Server started!
semDataOk.acquire();
Server started!
semDataOk.acquire();
semDataOk.acquire(),successed!
first
semDataOk.acquire();
semDataOk.acquire(),successed!
second
semDataOk.acquire();
semDataOk.acquire(),successed!
bye
Server finished!
写在文章的最后