ACE学習(五)ACE_Semaphore
3097 ワード
この信号量メカニズムはwin 32とlinuxでサポートされており、特に感じません.直接Demoは以下のように、このDemoも古典的な生産者消費者の実現である.
// thread_semaphore.cpp
#include "ace/Task.h"
#include "ace/Semaphore.h"
class Consumer:public ACE_Task <ACE_MT_SYNCH>
{
public:
enum{ N_THREADS = 5 };
Consumer(ACE_Semaphore& psema, ACE_Semaphore& csema):m_psema(psema), m_csema(csema), m_exitCondition(0)
{}
int isClose()
{
return m_exitCondition;
}
int svc(void)
{
while (!isClose())
{
consumeItem();
}
return 0;
}
void consumeItem()
{
m_csema.acquire();
if (!isClose())
{
ACE_Message_Block *mb;
this->getq(mb);
if (mb->msg_type() == ACE_Message_Block::MB_HANGUP)
{
shutdown();
mb->release();
return;
}
else
{
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Consumed %d
"), *((int *)mb->rd_ptr())));
mb->release();
}
m_psema.release();
}
}
void shutdown(void)
{
m_exitCondition = 1;
this->msg_queue()->deactivate();
m_csema.release(N_THREADS);
}
private:
ACE_Semaphore& m_psema;
ACE_Semaphore& m_csema;
int m_exitCondition;
};
class Producer:public ACE_Task_Base
{
public:
enum{MAX_PROD = 128};
Producer(ACE_Semaphore &psema, ACE_Semaphore &csema, Consumer &consumer)
:m_psema(psema), m_csema(csema), m_consumer(consumer)
{}
void producItem(int item)
{
m_psema.acquire();
ACE_Message_Block *mb = new ACE_Message_Block(sizeof(int),ACE_Message_Block::MB_DATA);
ACE_OS::memcpy(mb->wr_ptr(), &item, sizeof(item));
mb->wr_ptr(sizeof(int));
this->m_consumer.putq(mb);
ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) Prodeced %d
"), item));
m_csema.release();
}
int svc(void)
{
for (int i=0; i<=MAX_PROD; i++)
{
producItem(i);
}
hangUp();
return 0;
}
void hangUp()
{
m_psema.acquire();
ACE_Message_Block *mb = new ACE_Message_Block(0, ACE_Message_Block::MB_HANGUP);
this->m_consumer.putq(mb);
m_csema.release();
}
private:
ACE_Semaphore& m_psema;
ACE_Semaphore& m_csema;
Consumer& m_consumer;
};
int ACE_TMAIN(int, ACE_TCHAR *[])
{
ACE_Semaphore psem(5);
ACE_Semaphore csem(0);
Consumer consumer(psem, csem);
Producer producer(psem, csem, consumer);
producer.activate();
consumer.activate(THR_NEW_LWP | THR_JOINABLE, Consumer::N_THREADS);
producer.wait();
consumer.wait();
return 0;
};