-
Producer / CustomerOperations Dev/Producer 2010. 12. 10. 23:45
Producer.h
#pragma once#include <queue>
#include <string>#include "Concurrency\Thread.h"
#include "Customer.h"
#include "Concurrency\Timer.h"
#include "Concurrency\SpinLock.h"class Producer
{
public:
Producer(float frequency);
~Producer();
public:
void
beginService();
bool
tryPop( std::string * product);
private:
void service();private:
Thread * _thread;
std::queue< std::string > _products;//경쟁관계에 있는 녀석
Timer _timer;
float _frequency;
unsigned int _count;
volatile bool _isEnd;
SpinLock mylock;
};
Produce.cpp
#include "StdAfx.h"
#include "Producer.h"#include <Windows.h>
Producer::Producer(float frequency)//인자를 갖지 않는 생성자를 호출한다 기입하지 않으면, 파라미터를 받는 생성자를 만들었다면 기본생성자는 호출되지않는다.
: _count( 0 ),
_isEnd(false),
_frequency(frequency)
{
}void Producer::beginService()
{
_thread = new Thread( std::bind(&Producer::service, this));
}Producer::~Producer(void)
{
_isEnd = true;
::WaitForSingleObject( ( HANDLE )( _thread ), INFINITE); //반드시해주어야함 모든 자식 스레드를 종료해주기 위해 메인스레드가 종료하면 소멸자를
delete _thread;// 메인스레드가 종료될때 소멸자 호출,. 그러나 지금 스레드가 작동중이라면???
}
bool Producer::tryPop( std::string * product)
{
mylock.lock();
bool result = false;if( !_products.empty())
{
*product = _products.front();
_products.pop();
result = true;
}
mylock.unlock();
return result;}
void Producer::service()
{
_timer.start();
while( !_isEnd )
{
if(_timer.elapsedSeconds() >= _frequency)
{
char number[100];
itoa( _count, number, 10 );
std::string product = "product";
product += number;
++_count;
_timer.stop();
_timer.start();
mylock.lock();
_products.push( product );
mylock.unlock();
}
::Sleep(0); //원래는 블록큐로 가나, 0이니까 준비큐로가고 1초가 아닐때 다른작업할거있음 하라고 양보하는 것이다.
}
}
Customer.h
#pragma once#include "Concurrency\Thread.h"
#include "Concurrency\Timer.h"
#include "Concurrency\MutexLock.h"class Producer;
class Customer
{
public:
Customer( Producer * producer, // 포인터 타입으로 갖고 있게 한다. 인스턴스를 선언하지 않고, 클래스실체를 선언하지 않고 사용하는법
float frequency);
~Customer();public:
void
beginService();private:
void service();//백그라운드에서
private:
Thread * _thread;
Producer * _producer;
Timer _timer;
float _frequency;
volatile bool _isEnd;
};
Customer.cpp
#include "StdAfx.h"
#include <concrt.h>
#include <Windows.h>
#include "Customer.h"#include "Producer.h"//헤더에서 그냥 선언만해놓고 여기서 추가해주면 사용할수 있다.
Customer::Customer( Producer * producer,
float frequency)
: _producer( producer ),
_frequency( frequency ),
_isEnd(false)
{}
Customer::~Customer(void)
{
_isEnd = true;
::WaitForSingleObject( ( HANDLE )( _thread ), INFINITE);
delete _thread;
}
void Customer::beginService()
{
_thread = new Thread( std::bind(&Customer::service, this));
}
void
Customer::service()
{
_timer.start();while( !_isEnd)
{
if(_timer.elapsedSeconds() >= _frequency )
{
std::string product;if( _producer->tryPop(&product)) // 커스토머 쓰레드 호출되는 곳의 쓰레드이다.
{
printf( "%s\n", product.c_str() );_timer.stop();
_timer.start();
}}
::Sleep( _frequency * 250 );
}
}
ServiceThread.cpp
// ServiceThread.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.
//#include "stdafx.h"
#include<Windows.h>
#include "Customer.h"
#include "Producer.h"
int _tmain(int argc, _TCHAR* argv[])
{
Producer p(0.01f);
Customer c1( &p, 0.008);
Customer c2( &p, 0.005 );p.beginService();
::Sleep( 2000 );
c1.beginService();
c2.beginService();Timer timer;
timer.start();
while( timer.elapsedSeconds() < 20);return 0;
}'Operations Dev > Producer' 카테고리의 다른 글
종료 (0) 2010.12.11