일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 포트 번호 변경
- Git
- 키워드
- Flash Memory
- Machine Learning
- Cache
- storage system
- deep learning
- Operating System
- github
- performance
- software
- USENIX
- ssd
- core dumped
- Intel
- 커널 프로그래밍
- Samsung
- FTL
- overflow
- linux
- memory
- rocksdb
- kernel
- hardware
- 시스템 소프트웨어
- 시스템 프로그래밍
- framework
- Today
- Total
Happy to visit my research note ^^
pthread 본문
pthread를 알려면 thread에 대해서 먼저 알아야한다. thread의 사전적 의미는 process 내에서 실행되는 여러 흐름의 단위이다. 하나의 process 안에서 여러개의 thread가 돌아가서 동시에 여러개를 처리하는 것처럼 보이게 하는것이다.
그럼 process를 여러 개 실행시키는 multi-tasking이 있는데 thread는 왜 쓰는 가에 대한 질문을 해결해보자.
multi-tasking은 여러 개의 process를 돌아가면서 실행시켜서 동시에 동작하는 것처럼 보이게 하는것을 말한다. 간단한 예시로는 하나의 CPU로 이루어진 컴퓨터에서 웹 서핑 + 유튜브 + ppt 작업을 한다고 가정해보자. multi-tasking을 지원하는 OS 위에서는 세 가지 process들을 동시에 동작시킬 수 있다. 이 세 작업을 짧은 시간동안 번갈아서 실행함으로써 마치 동시에 세 작업을 실행하고 있다고 느끼게 되는 것이죠. 그러나, 이 방식으로 작동하면 한 process에서 다른 process로 넘어갈 때, 교환되는 도중에는 CPU가 대기상태가 돼서 이만큼의 CPU 성능을 사용하지 못하게 된다.
그래서, 여러개의 process를 만드는게 아니라, 하나의 process안에 thread를 생성해서 여러 개의 thread가 돌아가면서 동작하게 되면 context switching이 될 때 걸리는 시간을 줄일 수 있고 이로인해, 전체적인 시스템 성능을 향상시킬 수 있게 된다.
thread의 장점은:
1. context switching 시간이 짧다. 2. memory sharing으로 인해서 system resource의 소모가 적다. 3. response time이 줄어든다.
다시 pthread로 돌아오면, pthread는 POSIX thread의 약자로 UNIX 계열 POSIX system에서 병렬적으로 작동하는 software를 작성하기 위해 제공되는 API이다. 즉, thread를 편하게 만들 수 있게 도와주는 API인 셈이다.
코드로 확인을 해보면:
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void *p_function(void *data){
pid_t pid; // process id
pthread_t tid; // thread id
pid = getpid();
tid = pthread_self();
char *thread_name = (char *)data;
int i = 0;
while(i < 3){
printf("thread name : %s, tid : %x, pid : %u\n",
thread_name, (unsigned int)tid, (unsigned int)pid);
i++;
sleep(1);
}
}
int main(void){
pthread_t pthread[2];
int thr_id;
int status;
char p1[] = "thread_1";
char p2[] = "thread_2";
char p3[] = "thread_3";
sleep(1);
thr_id = pthread_create(&pthread[0], NULL, p_function, (void*)p1); //2
if(thr_id < 0) {
perror("pthread0 create error");
exit(EXIT_FAILURE);
}
thr_id = pthread_create(&pthread[1], NULL, p_function, (void *)p2); //2
if(thr_id < 0) {
perror("pthread1 create error");
exit(EXIT_FAILURE);
}
p_function((void *)p3); //3
pthread_join(pthread[0], (void **)&status); //6
pthread_join(pthread[1], (void **)&status);
printf("end??\n");
return 0;
}
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
첫번째 매개변수는 thread identifier이다. 생성된 thread를 구별하기 위한 id
두번째 매개변수는 thread 특성을 지정하기 위해 이용하는데 보통은 NULL로 쓴다.
세번째 매개변수는 thread가 실행되었을 때 시작할 thread 함수이름이다.
네번째 매개변수는 thread가 분기할 함수에 보낼 입력 parameter이다. 즉, 새로운 thread가 실행할 함수에 보낼 parameter인 것이다.
return value는 생성된 thread 의 id이다.
이로 인해 생성된 thread는 parent thread로부터 새로운 thread로 분리되어서 독립적인 실행 경로를 따르게 된다. 세번째 parameter인 start_routine이 새로운 thread가 실행할 함수를 가리킨다.
이 코드가 실행되면 하나의 thread가 생성되어 총 두개의 thread(main, thread1)이 동작하게 된다. 이 코드를 실행하면 총 3개의 thread가 동작하고 있다는 것을 알 수 있다.
int pthread_join(pthread_t th, void **thread_return);
main을 도는 thread가 자신으로부터 branch된 thread들이 종료되기를 기다리는 함수이다.
첫번째 parameter는 thread identifier이다. pthread_create의 첫 parameter와 같다.
두번째 parameter는 return value
pthread_t pthread_self(void);
- 현재 동작중인 pthread의 식별자를 리턴한다.
위에서 소개한 pthread_create는 posix thread library 일부로 new thread 생성한다. 여기서는 pthread에 대한 추가적인 정보들을 소개한다.
pthread_t
thread는 process 내에서 고유한 thread ID로 구분하게 되는데, 이 thread ID를 나타내는 데이터 타입이 pthread_t이다. pthread_t 는 OS마다 다르게 구현되어 있기 때문에 다양한 데이터 타입으로 구현할 수 있도록 허용되어 있다.