Skip to content
 

리눅스 데몬 개발 3/8

3 장 : thread

많은 데몬 개발 또는 통신 프로그램에서 fork()를 많이 이용한다.
하지만 필자는 fork보다는 thread 를 더 선호하는 편이다.

fork()는 단순 클라이언트의 경우에 상당히 유리하고 간단하게 개발할 수 있는 반면에 클라이언트간에 데이타 공유나 전송에는 오히려 더 어려운 코딩을 해야 하기 때문이다.

fork()가 진정한 child프로세서를 만드는 기법이라면 thread는 윈도우의 개발 방식과 상당히 유사하기 때문에 윈도우 클라이언트와 연동하는 모델의 서버를 개발한다면 thread쪽을 더 권장한다.

thread 가 fork()와 가장 다른점은 함수단위의 스래드 처리가 가능하기 때문에 global 변수나 기타 다른 함수의 데이타 공유가 가능하다는 점이다. 하지만 이런한 편의성은 두 스래드간에 동시 자료 접근으로 인한 결함도 야기된다. 예를 들어 두 스래드가 동시에 트리 또는 큐같은 메모리를 사용하게 되면 데이타의 연결고리가 끝어질 수 있는 단접이 있다. 이런 경우에 이후에 설명할 예정인 세마포 또는 뮤택스와 같은 동기 함수를 이용하는 코딩 기법이 필요하게 된다.

이번 예제에서 가장 중요한 포인트는 cnt라고 하는 global변수가 fork()방식으로 했을때 parent와 child가 각각 다른 변수로 인식되는 반면 thread에서는 같은 변수로 사용이 되는 접을 알수 있는 소스다.

아래의 소스를 실행해보면 cnt가 중간에 바뀌고 나서 thread에서 출력시에도 바뀐 값을 똑같이 출력하는것을 확인 할 수 있다.

다중 타스크 프로그램에서 fork와 thread어느쪽이 정답이하고는 할수 없다.
그건 while 이냐 for 냐의 구분과 비슷할 것이다.
하지만 이 두 방식의 차이를 정확히 이해한다면 데몬 개발에서는 상당히 편리한 코딩을 할 수 있게 된다.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

int cnt = 0;

void *fun( void *arg )
{
printf( “This is child : %d
“, getpid() );
sleep( 3 );
printf( “child end : %d
“, cnt );

pthread_exit( NULL );
return 0;
}

void main( int argc, char *argv[] )
{
pthread_t t;
pthread_create( &t, NULL, fun, NULL );

cnt = 10;

printf( “This is parent : %d
“, getpid() );
sleep( 5 );
printf( “server end : %d
“, cnt );
}

=============================
This is child : 12325
This is parent : 12323
child end : 10
server end : 10

Leave a Reply