清单 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<
即使在所有进程都与之脱离之后,这个共享内存也不会被销毁。这样您就可以使用 ipcrm 显式地删除,或者使用 ipcs 命令进行查看。测试程序的编译方式如下:
g++ -g -o shm_client shm_client1.cpp ObjectWithEvents.cpp Initializer.cpp
控制台上运行这个程序的结果如下所示:
内容导航