Monday, May 19, 2008

Thread, Basic

LSP에서는 thread를 다루고 있지 않다. 그래서 APUE의 내용을 통해 복습해 보려고 한다. 알다시피 thread는 한 프로세스 내에서 여러개로 되어 동작하기 때문에 프로세스 내의 메모리나 fd를 공유한다. 그렇기 때문에 이러한 프로세스 내 공유 자원들에 접근할 때는 항상 consistency를 생각해야 한다. thread를 사용하는 일반적인 장점들은 아래와 같다.

  • asyncronous event를 다루는 루틴을 event type에 따라 별개의 thread를 만들어 처리하면 코드가 간단해진다.

  • 여러 프로세스들을 사용하면서 fd, memory를 공유하려면 복잡한 커널의 system call을 사용해야하는 반면에 thread에서는 간단하게 처리할 수 있다.

  • 한 thread에서 직렬로 진행되던 루틴들이 병렬화 되어 성능 향상을 가져올 수 있다.

  • Single processor에서도 성능향상이 있을 수 있다(한 thread가 block일때 다른 thread는 돌 수 있으므로)

  • multiple thread를 사용하므로써 사용자 응답시간이 좋아진다(user input/output을 thread로 돌리면 되므로) .

  • Multi-processor 환경에서 성능 향상을 가져다 준다.


한개의 thread는 여러 정보들을 가지고 있는데 아래와 같다.

  • thread ID, 레지스터 값들, 스택, 스케쥴 priority, policy, signal mask and errno


소위 pthread라 불리는 것들은 POSIX.1-2001의 optional feature이다. 이게(optional한 부분이) 지원되는지 안되는지는 _POSIX_THREADS 를 #ifdef로 테스트 해보면 된다(아님, sysconf에서 _SC_THREADS로 호출해보거나..)

thread identification pid_t 처럼 thread에서는 pthread_t 를 쓴다. 그런데, 구현에 따라 pthread_t를 구조체로 만드는 경우도 있기 때문에 tid1 == tid2 식으로 비교할 수는 없고 아래 함수를 사용한다. 자신의 tid를 보기 위해서는 pthread_self()를 사용한다.

#include <pthread.h>
int pthread_equal(pthread_t tid1, pthread_t tid2);
pthread_t pthread_self(void);

일단 thread 만드는 함수를 알아야 할텐데, 아래와 같다.

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg);

좀 어려워 보이지만 인자부터 체크해보자, 첫번째는 tid가 반환 될 것이고 두번째는 attributes를 넘겨줄 때 쓴다. 새로 생성된 thread는 start_rtn 루틴 부터 시행을 시작할 것이고, 이 함수는 arg를 인자로 받는다. thread는 signal mask를 상속받지만, pending 되어 있던 signal들은 clear된다. 조심할 점은 thread가 만들어지면 어떤 것이 먼저 실행될지 알 수 없다는 것이다. 대충 알았으니 한번 만들어보자.

#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

pthread_t ntid;

void * thr_func(void *arg)
{
printf("new thread id(%u)pid(%u)\n",
(unsigned int)pthread_self(), (unsigned int)getpid());

return (void *)0;
}

int main()
{
int err;

err = pthread_create(&ntid, NULL, thr_func, NULL);
if (err != 0)
fprintf(stderr, "pthread_create error\n");

printf("main thread id(%u)pid(%u)\n",
(unsigned int)pthread_self(), (unsigned int)getpid());
sleep(1);
return 0;
}

linux에서는 pid가 다른 경우도 있고, tid는 4자리로 나타나는 것으로 되어 있는데, 실제 돌려보니 pid가 같고, tid도 연관성이 없는 것처럼 보인다(FreeBSD처럼 나온다) 왜일까. pthread_self 대신 gettid()를 사용하면 pid와 비슷하게 생긴 tid를 얻을 수 있다.

No comments:

Post a Comment