2009년 07월 01일
Asynchronous Component
프로그램을 제작하다 보면, 필연적으로 Database와 소켓, 파일 관련된 코드를 쓰게 된다.
아무리 CPU 성능이 좋아도 이와 같은 기능을 사용하게 되면 io blocking이 발생하고, 프로그램 성능에 치명적인 문제를 일으키게 되기 때문에 쓰레드를 사용해야 한다.
쓰레드는 판도라의 상자!
쓰레드를 생성하는건 간단하지만, 멀티쓰레드 디버깅을 해본 사람이라면 쓰레드 하나 만드는데도 고심을 많이 할 것이다.
이유는 데드락과 동기화 문제가 발생하면서, 코드분석 난이도가 성큼 올라가버리기 때문이다.
간단한 멀티쓰레드 프로그래밍을 해보자
396
397
398 struct Dosomething
399 {
400 operator()
401 {
402 while( 1 )
403 {
404 GetQuery(query, fn);
405 //쿼리를 가져옴
406 Execute(string query);
407 //쿼리 실핼
408 Call();
409 //콜백함수 호출
410 }
411 }
412 };
413
414 void OnSelectTbTest()
415 {
416 //쿼리콜백
417 };
418
419 int main()
420 {
421 Dosomething t; //쓰레드 돌릴 구조체
422 thread(ref(t)); //쓰레딩 시작
423
424 t.ExecuteScala("select * from tb_test", OnSelectTbTest);
// 쓰레드에안전한명령실행함수
425
426 //DoSomeThing...
보통은 클래스에 멤버 함수 콜백을 이용하지만 편의상 전역 함수로 작성하였다.
아마 대부분은 이러한 구조로 쓰레딩을 처리할것이다.
그리고 반드시 잊지 말아야 할것은 OnSelectTbTest로 콜백을 받았을때 처리방법이다.
OnSelectTbTest의 호출자는 메인 쓰레드가 아닌 워커 쓰레드다.
동시 접근이 가능한 함수이므로 여기에 쓰이는 코드는 모두 쓰레드에 안전해야 한다.
한 두개 정도야 락으로 처리 한다지만
Database 쿼리 같은경우 수십개로 늘어 날수 있는데 할때마다 동기화 처리를 해줄것인가?
그뿐만 아니라 세밀한 락을 걸려면 노가다성이 짙고, 자칫하면 동기화 에러를 발생할수도 있다.
그래서 고안한게 비동기 컴포넌트다.
코드상으로는 똑같이 여러개의 쓰레드로 구현되지만, Lock 이 필요없다.
86 Game:Game(void)
87 {
88 OdbcClient client = new OdbcClient;
89 client->OnCompleted += new EventHandler<DataEventArg>( this, &Game::OnCompleted );
90 client->ExecuteScala("select * from tb_test"); //long-running func..
91 Add( client );
92 }
93
94 void Game::OnCompleted( Component& sender, DataEventArg* e )
95 {
96 if( e->succeed == true )
97 printf("Succeed");
98 else
99 printf("Fail");
100 }
101
102 int main()
103 {
104 Game game;
105 Application.Run(game);
106
107 //DoLoop
108 }
코드로 보면 위의 함수 콜백과 별반 다르지 않다.
OdbcClient란 콤포넌트는 자체적으로 쓰레드를 생성한다.
그후 Game 클래스에서 비동기 호출을 하고 콜백함수가 올때까지 기다린다.
하지만 전의 코드와는 다르게 OnCompleted의 호출자는 ExecuteScala를 호출한 쓰레드이다!
따라서 OnCompleted에 대해 락을 걸필요가 없다.
내부적으로 함수 호출 큐를 가지고 있기때문에 직접 호출하는게 아니라 메세지 큐로 거쳐서 호출되기 때문이다.
이렇게 함으로써 동기화에 좀더 자유로울수 있고, 데이터만 동기화 함으로써 락의 지연시간을 최소화 할수 있었다.
[어디선가 이러한 구조를 누군가 생각하지 않았을까 했는데, MS가 1년전부터 쓰고 있었다는 글을 보았다. 나의 기술 동기화는 1년 전이란 얘긴가 ㅠㅠ]
# by | 2009/07/01 22:59 | 트랙백 | 덧글(0)



