随着计算机技术的发展,CPU,内存等硬件性能的急速攀升,人们也对自己使用程序有了越来越高的要求。
进程间通信(InterProcess Communication, IPC)也变成了一个必不可少的技术点。简单来说:进程间通信就是进程间相互交换数据的机制。
现有的进程间通信方式有多种:共享内存,文件映射,匿名管道,命名管道,消息队列,信号量、邮件槽,剪贴板,动态数据交换,对象连接与嵌入,动态连接库,远程过程调用,Sockets 等。不同的系统,不同的库提供的实现方式也有差异。
但是对于学习来说,我们没有必要掌握那么多,一下我们一些主流的进程间通信技术
信号量(semaphore)
简单说:它是一个计数器,用于使用进程间的互斥与同步。信号量基于操作系统的PV操作,每次对信号量的PV操作可以加减任何正整数。有一个缺点不能传输数据
等待App:
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "等待 App start " << &app << " : " << QTime::currentTime();
QSystemSemaphore oSem("SystemSemaphore key", 0);
oSem.acquire(); // 如果取不到就一直阻塞在这里
qDebug() << "等待 App down " << &app << " : " << QTime::currentTime();
return app.exec();
}
释放 App:
void sleep(unsigned int msec)
{
QTime reachTime=QTime::currentTime().addMSecs(msec);
while(QTime::currentTime()<reachTime)
{
QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "释放 App start " << &app << " : " << QTime::currentTime();
QSystemSemaphore oSem("SystemSemaphore key", 0);
oSem.release(1);
sleep(100);
qDebug() << "释放 App down " << &app << " : " << QTime::currentTime();
return app.exec();
}
运行结果:
等待 App start QCoreApplication(0x60fdb0) : QTime("22:52:27.443")
等待 App down QCoreApplication(0x60fdb0) : QTime("22:52:33.347")
释放 App start QCoreApplication(0x65fd40) : QTime("22:52:33.336")
释放 App down QCoreApplication(0x65fd40) : QTime("22:52:33.446")
本实例使用的是Qt控件QSystemSemaphore,acquire和release函数对应PV操作。使用第三方库有好处:可以做到平台无关,控件更好用。也有问题:效率可能不如平台API性能好。
共享内存(Shared Memory)
简单说:多个进程共享一个给定的存储区,数据传输快。有一个缺点需要增加其他控制类型的通信配合。
Deom中用信号量配合共享内存,这也是最常见的配合方式。
等待App:
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "等待 App start " << &app << " : " << QTime::currentTime();
QSystemSemaphore oSem("SystemSemaphore key", 0);
QSharedMemory oSharedString("SharedMemory key");
oSem.acquire(); // 如果取不到就一直阻塞在这里
qDebug() << "等待 App 获得sem" << &app << " : " << QTime::currentTime();
if (oSharedString.attach())
{
oSharedString.lock();
char* d = reinterpret_cast<char*>(oSharedString.data());
qDebug() << "等待 App : " << d;
oSharedString.unlock();
oSharedString.detach();
}
qDebug() << "等待 App down " << &app << " : " << QTime::currentTime();
return app.exec();
}
释放 App:
void sleep(unsigned int msec)
{
QTime reachTime=QTime::currentTime().addMSecs(msec);
while(QTime::currentTime()<reachTime)
{
QCoreApplication::processEvents(QEventLoop::AllEvents,100);
}
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "释放 App start " << &app << " : " << QTime::currentTime();
QSystemSemaphore oSem("SystemSemaphore key", 0);
QSharedMemory oSharedString("SharedMemory key");
if (oSharedString.create(1024))//申请1024字节的内存
{
oSharedString.lock();//加锁
char* d = reinterpret_cast<char*>(oSharedString.data());
std::string sHello = "hello";
d = const_cast<char*>(sHello.data());
memcpy(oSharedString.data(),d,strlen(d)*sizeof(char));//把数据写入内存
oSharedString.unlock();//解锁
}
oSem.release(1);
sleep(100);
qDebug() << "释放 App down " << &app << " : " << QTime::currentTime();
return app.exec();
}
运行结果:
等待 App start QCoreApplication(0x65fcc0) : QTime("23:26:58.790")
等待 App 获得sem QCoreApplication(0x65fcc0) : QTime("23:27:01.251")
等待 App : hello
等待 App down QCoreApplication(0x65fcc0) : QTime("23:27:01.264")
释放 App start QCoreApplication(0x65fd30) : QTime("23:27:01.241")
释放 App down QCoreApplication(0x65fd30) : QTime("23:27:01.351")