Half sync/Half Async
-
Upload
scor7910 -
Category
Technology
-
view
982 -
download
1
Transcript of Half sync/Half Async
Half-Sync/Half-Async
아키텍트를 꿈꾸는 사람들
발표 : 김연기
Context
동기 IO 와 비동기 IO를 어떻게하면 사이 좋게 지내게 할수 있을까??
Problem
비동기 IO나 동기IO로 인한 아키텍쳐의 복잡도에 영향을 끼쳐서는 안된다.
비동기 IO작업과 동기 IO작업간의 통신으로 인한 성능저하가발생 해서는 안된다.
Solution
비동기 IO Layer와 동기IO Layer를 분리하여, Queueing layer 를 두어 두 Layer가 서로통신할 수 있도록 한다.
Structure
Class : Synchronous Layer
Responsibility: 동기 IO 처리Collaborator : Queueing
Layer
Class : Asynchronous Layer
Responsibility: 비동기 IO 처리
Collaborator : Queueing LayerExternal EventSource
Class : Queueing Layer
Responsibility: 비동기 Layer와 동기 레이어간 데이터 전달역할.Collaborator : 비동기 Layer
동기 Layer
Class : External Event Source
Responsibility: 비동기 Layer 에서 발생하는 IO에 대한 이벤트 처리.Collaborator : 비동기 Layer
Structure (2)
Synchronous Service Layer
Queueing Layer
AsynchronousService Layer
External Event Source
Async Service
Queue
Sync Service 1 Sync Service 2 Sync Service 3
Dynamics
Implementation동기 IO Layer와 비동기 IO Layer 를 나눈다. 동기 IO Layer 구현비동기 IO Layer 구현
External Event Source 구현Queueing Layer 구현
Queue는 Thread Safe하게 구현!! Sync Layer와 Async Layer에 어떻게 알려주고 통신이 되게할건가??
Implementation(2)intACE_Message_Queue_NT::enqueue (ACE_Message_Block *new_item,
ACE_Time_Value *){ACE_TRACE ("ACE_Message_Queue_NT::enqueue");
ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);if (this->state_ != ACE_Message_Queue_Base::DEACTIVATED){size_t const msize = new_item->total_size ();size_t const mlength = new_item->total_length ();// Note - we send ACTIVATED in the 3rd arg to tell the completion// routine it's _NOT_ being woken up because of deactivate().ULONG_PTR state_to_post;state_to_post = ACE_Message_Queue_Base::ACTIVATED;if (::PostQueuedCompletionStatus (this->completion_port_,
static_cast<DWORD> (msize),state_to_post,reinterpret_cast<LPOVERLAPPED> (new_item)))
{// Update the states once I succeed.this->cur_bytes_ += msize;this->cur_length_ += mlength;return ACE_Utils::truncate_cast<int> (++this->cur_count_);
}}
elseerrno = ESHUTDOWN;
// Fail to enqueue the message.return -1;
}
Implementation(2)intACE_Message_Queue_NT::dequeue (ACE_Message_Block *&first_item,
ACE_Time_Value *timeout){ACE_TRACE ("ACE_Message_Queue_NT::dequeue_head");
{ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
<<생략>>// Get a message from the completion port.int retv = ::GetQueuedCompletionStatus (this->completion_port_,
&msize,&queue_state,reinterpret_cast<LPOVERLAPPED *> (&first_item),(timeout == 0 ? INFINITE : timeout->msec ()));
{ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);--this->cur_thrs_; // Decrease waiting thread count.if (retv){if (queue_state == ACE_Message_Queue_Base::ACTIVATED){ // Really get a valid MB from the queue.--this->cur_count_;this->cur_bytes_ -= msize;this->cur_length_ -= first_item->total_length ();return ACE_Utils::truncate_cast<int> (this->cur_count_);
}else // Woken up by deactivate () or pulse ().
errno = ESHUTDOWN;}
}return -1;
}
Conclusion구조가 더 간단해 지고 성능에 영향을 주지 않는다.Sync IO 와 Async IO 레이어의 분리로 상호 의존관계가 없어진다.
메모리 Copy나 Thread 동기화 등에 대한 처리를 주의 깊게 해야한다.디버깅이나 테스트하기 복잡하다.
참고 자료ACEhttp://www.cs.wustl.edu/~schmidt/ACE.html