科技行者

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

知识库

知识库 安全导航

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

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

  • 扫一扫
    分享文章到微信

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

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

作者:51cto 2007年10月14日

关键字:

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

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

清单 5. 修改 ObjectWithEvents.cpp
// To add a declaration for the "new" operator:
class ObjectWithEvents : public IObjectWithEvents
{
public:void * operator new(unsigned int);
};
// To include an additional header for the Initializer class:
#include "Initializer.h"
// To overload the operator "new":
void * ObjectWithEvents::operator new(unsigned int)
{return ms_pObjectWithEvents;
}
// Then, FireEvent is completely changed:
void ObjectWithEvents::FireEvent()
{// We need to serialize all access to the collection by more than one processint iRetVal = Initializer::LockMutex();
if (0 != iRetVal){return;}
pid_t pid = getpid();
// iterate through the collection and fire only events belonging to the current processfor (long i = 0; i < m_npEI; i++){// Check whether the handler belongs to the current process.if (pid != m_alPID[i]){continue;}
//Recheck for NULLif (0 != m_apEI[i]){m_apEI[i]->OnEvent(pid, "");}}
// release the mutexif ((0 == iRetVal) && (0 != Initializer::UnlockMutex())){// Deal with error.}
return;
}
// The following are changes to ObjectWithEvents::AddEventHandler():
// 1. Before accessing the collection, we lock the mutex:
int bRetVal = Initializer::LockMutex();
if (0 != bRetVal)
{return false;
}
// 2. After accessing the collection, we release the mutex:
if ((0 == bRetVal) && (0 != Initializer::UnlockMutex()))
{// Deal with error.
}
要对共享内存中的对象进行实例化,请定义另外一个类 Initializer。
清单 6. Initializer.h
#ifndef __Initializer_H__
#define __Initializer_H__
class Initializer
{
public : int m_shmid; static Initializer ms_Initializer; Initializer();
 static pthread_mutex_t ms_mutex; static int LockMutex(); static int UnlockMutex();
};
#endif // __Initializer_H__
Initializer 定义了共享内存的 id m_shmid 和一个用来处理同步事件的信号量 ms_mutex。
函数 LockMutex() 负责对这个互斥体进行加锁,UnlockMutex() 对这个互斥体进行解锁。
Initializer 的实现如清单 7 所示:
清单 7. Initializer.cpp
#include 
#include 
#include 
#include 
#include 
#include "Initializer.h"
#include "ObjectWithEvents.h"
using namespace std;
Initializer Initializer::ms_Initializer;
pthread_mutex_t Initializer::ms_mutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
Initializer::Initializer() : m_shmid(-1)
{bool bCreated = false;key_t key = 0x1234;
m_shmid = shmget(key,sizeof(ObjectWithEvents), 0666);
if (-1 == m_shmid){if(ENOENT != errno){cerr<<"Critical Error"<
如果共享内存尚不存在,就创建共享内存;并在其中创建对象。如果共享内存已经存在了,就跳过对象的构建。Initializer::m_shmid 记录了这个标识符,ObjectWithEvents::ms_pObjectWithEvents 记录了对这个共享对象的引用。
即使在所有进程都与之脱离之后,这个共享内存也不会被销毁。这样您就可以使用 ipcrm 显式地删除,或者使用 ipcs 命令进行查看。测试程序的编译方式如下:
g++ -g -o shm_client shm_client1.cpp ObjectWithEvents.cpp Initializer.cpp
控制台上运行这个程序的结果如下所示:
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

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

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