科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网网络频道在Linux上处理共享对象的同步事件

在Linux上处理共享对象的同步事件

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

调用进程或向这个对象发送消息的线程在发送消息调用完成之前都会接收并处理一系列事件。然而,如果产生这些事件的对象是由多个进程进行共享并且保存在共享内存中时,情况就稍微有些不同了。

作者:51cto 2007年10月14日

关键字: Linux 共享对象 同步 处理

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共3页)

  在面向对象的系统中,当一个对象接收到一条消息时,可能会发生一系列的事件。通常,这些事件是以 同步(synchronous) 模式处理的:调用进程或向这个对象发送消息的线程在发送消息调用完成之前都会接收并处理一系列事件。然而,如果产生这些事件的对象是由多个进程进行共享并且保存在共享内存中时,情况就稍微有些不同了。

  本文将使用两种 C++ 设计模式来详细介绍这种情况,并使用一些样例代码来展示这种解决方案(这些样例代码可以从本文 下载 一节中获得):

  我们将简要介绍不使用共享内存的样例代码。

  使用第一种设计模式来修改这些代码,让其使用共享内存。

  然后阐述如何使用第二种设计模式来实现进程间通信(IPC)。 您可以在任何机器体系架构、操作系统和编译器上应用这两种设计模式中的概念。对于本文来说,我们使用的是 RedHat Linux 7.1 for 32-bit x86 Intel? 体系架构的发行版;使用 GNU C++ compiler version 3.2.3 编译器及其相关工具来编译并测试样例程序。

  不使用共享内存

  下面让我们开始介绍这个样例程序,首先是不使用共享内存的程序:

  清单 1. common.h<

  #ifndef __COMMON_H__

  #define __COMMON_H__

  class IObjectWithEvents

  {

  public:class IEventSink{public:virtual void OnEvent(pid_t pid, const char * msg) = 0;};

  static IObjectWithEvents * getInstance();

  virtual bool AddEventHandler(IEventSink * pEI) = 0;virtual void SendMessage() = 0;

  };

  #endif //__COMMON_H__

  

  接口类 IObjectWithEvents 包含了一个内嵌的接口类 IEventSink,它定义了 OnEvent() 方法。这个事件处理程序接收一个发送者的 id 和一个字符串消息。getInstance() 方法返回对共享内存中对象的引用,AddEventHandler() 注册一个事件处理程序,SendMessage() 向这个对象发送一条消息。由于不需要引用共享内存,所以可以像清单 2 中那样来使用 IObjectWithEvents:

  清单 2. shm-client1.cpp<

  #include

  #include

  #include

  #include "common.h"

  #define HERE __FILE__ <<":" <<__LINE__ <<" "

  using namespace std;

  class EventSink : public IObjectWithEvents::IEventSink

  {

  public:void OnEvent(pid_t pid, const char * msg){cout <清单 3. ObjectWithEvents.h

  #include "common.h"

  class ObjectWithEvents : public IObjectWithEvents

  {

  public:// We assume singleton design pattern for illustrationstatic ObjectWithEvents * ms_pObjectWithEvents;

  ObjectWithEvents();

  //the implementation for IObjectWithEventsvoid FireEvent();virtual bool AddEventHandler(IEventSink * pEI);virtual void SendMessage();

  //Collection for maintaining eventsenum { MAX_EVENT_HANDLERS = 16, };long m_npEI;IEventSink * m_apEI[MAX_EVENT_HANDLERS];pid_t m_alPID[MAX_EVENT_HANDLERS];

  };

  

  清单 4. ObjectWithEvents.cpp

  #include

  #include

  #include

  #include

  #include

  #include "ObjectWithEvents.h"

  using namespace std;

  ObjectWithEvents * ObjectWithEvents::ms_pObjectWithEvents = NULL;

  IObjectWithEvents * IObjectWithEvents::getInstance()

  {// the following commented code is for illustration only./*if (NULL == ObjectWithEvents::ms_pObjectWithEvents){ObjectWithEvents::ms_pObjectWithEvents = new ObjectWithEvents();}*/

  return ObjectWithEvents::ms_pObjectWithEvents;

  }

  ObjectWithEvents::ObjectWithEvents() : m_npEI(0)

  {

  }

  void ObjectWithEvents::FireEvent()

  {// iterate through the collectionfor (long i = 0; i OnEvent(m_alPID[i], "");}}

  return;

  }

  bool ObjectWithEvents::AddEventHandler(IEventSink * pEI)

  {// NULL checkif (NULL == pEI){return false;}

  // check if there is space for this event handlerif (MAX_EVENT_HANDLERS == m_npEI){return false;}

  // Add this event handler to the collectionm_alPID[m_npEI] = getpid();m_apEI[m_npEI++] = pEI;

  return true;

  }

  void ObjectWithEvents::SendMessage()

  {//Some processing//And then fire the event

  FireEvent();

  return;

  }

  

  清单 4 中的代码可以使用下面的脚本来编译:

  g++ -g -o shm_client shm_client1.cpp ObjectWithEvents.cpp

  

  在运行 shm_client 时,应该可以看到下面的输出:

  $ ./shm_client shm_client1.cpp:16 Message from pid(3920) :

  

  使用共享内存:没有事件缓存

  现在,为了在共享内存中对 ObjectWithEvents 进行实例化,我们需要修改 ObjectWithEvents 的实现。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章