More pthread functions
If I call pthread_create twice, how many stacks does my process have?
프로세스는 각각의 쓰레드마다 한개씩 총 3개의 스택을 가질 것입니다. 처음 쓰레드는 프로세스가 시작될 때 만들어지고, 두 번의 pthread_create로 2개가 더 만들어질 것입니다. 사실 이것보다 더 많은 스택이 존재하지만, 지금은 이런 복잡한 것들을 무시하겠습니다. 가장 중요한 개념은 각각의 쓰레드가 스택을 필요로 한다는 것입니다. 왜냐하면 스택에는 automatic variable들과 이전 CPU PC register를 가지고 있기 때문에 함수가 끝난 후 호출한 함수로 돌아갈 수 있습니다.
What is the difference between a full process and a thread?
프로세스와 달리 한 프로세스 안에 쓰레드들은 같은 global memory(힙과 데이타 segment)를 공유합니
다.
What does pthread_cancel do?
쓰레드를 정지해줍니다. 쓰레드가 사실 즉시 정지하는 것은 아니라는 것을 알고 있어야 합니다. 예를 들면 thread가 Operating system call(write와 같은)을 호출했을 때 종료되어집니다.
사실 pthread_cancel은 잘 쓰이지 않습니다. 왜냐하면 쓰레드에게 스스로 정리할 기회를 주지 않기 때문입니다(어떤 파일을 열거나 했다면). 이 경우 boolean value를 이용해 다른 쓰레드에게 알려주어 finish와 cleanup을 할 수 있도록 해줄 수 있습니다.
What is the difference between exit and pthread_exit?
exit(42) 는 프로세스의 exit value를 42로 설정하고 프로세스를 빠져나갑니다. 이러한 사용은 main method에서 return 42와 같습니다. 프로세스 안의 모든 쓰레드가 멈추게 됩니다.
pthread_exit(void *)는 호출한 쓰레드만을 정지시킵니다. 즉 pthread_exit가 호출된 이후에는 쓰레드가 return되지 않습니다. Pthread library는 동작중인 다른 쓰레드가 없다면 자동적으로 프로세스를 끝내줄 것입니다. pthread_exit(...)은 쓰레드 function에서 리턴해주는 것과 같습니다. 둘 모두 쓰레드를 종료하고 return value를 (void *pointer)로 설정합니다.
main에서 pthread_exit를 호출하는 것은 단순한 프로그램에서 모든 쓰레드가 종료된 것을 보증하는 일반적인 방법입니다. 다음과 같은 프로그램을 예로 들면 myfunc theread는 시작할 시간이 없을 것입니다.
int main() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, myfunc, "Jabberwocky"); pthread_create(&tid2, NULL, myfunc, "Vorpel"); exit(42); //or return 42; // No code is run after exit }
이 아래에는 새롭게 생긴 쓰레드가 종료되는 것을 기다리는 두 가지 프로그램을 소개하겠습니다.
int main() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, myfunc, "Jabberwocky"); pthread_create(&tid2, NULL, myfunc, "Vorpel"); pthread_exit(NULL); // No code is run after pthread_exit // However process will continue to exist until both threads have finished }
위와 같이 pthread_exit를 이용하거나,
int main() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, myfunc, "Jabberwocky"); pthread_create(&tid2, NULL, myfunc, "Vorpel"); // wait for both threads to finish : void* result; pthread_join(tid1, &result); pthread_join(tid2, &result); return 42; }
pthread_join을 이용해 main에서 return하기 전에 쓰레드가 끝나기를 기다립니다.
이 두가지 중 위의 pthread_exit를 사용하면 thread zombie를 생성합니다. 하지만 오랫동안 동작하는 프로세스가 아니라면 크게 문제는 없습니다.
How can a thread be terminated?
- Thread function에서 return되었을 경우
- pthread_exit가 호출되었을 경우
- pthread_cancel로 thread가 cancel되었을 경우
- 프로세스가 종료되었을 경우 - SIGTERM, exit(), main에서의 return
What is the purpose of pthread_join
종료된 쓰레드들은 자원을 계속 소모합니다. 결국, 충분한 쓰레드가 만들어지고 나면 pthread_create는 실패하게 됩니다. 사실, 이러한 문제는 오랫동안 동작하는 프로세스의 경우에만 발생합니다. 주기가 짧은 프로세스는 프로세스가 종료될 때 쓰레드의 리소스를 모두 자동적으로 free시켜줍니다.
Should I use pthread_exit or pthread_join?
pthread_exit나 pthread_join 모두 다른 쓰레드가 스스로 끝나기를 기다립니다(main thread에서 호출되어도 마찬가지). 하지만 pthread_join만이 특정한 쓰레드가 종료되었을 때 return해줄 수 있습니다. pthread_exit는 기다리지 않고 즉시 쓰레드를 종료시켜 다음 실행을 계속할 기회를 주지 않습니다.
Can you pass pointers to stack variables from on thread to another?
가능합니다. 하지만 stack variable의 lifetime에 주의해서 사용해야합니다.
pthread_t start_threads() {
int start = 42;
pthread_t tid;
pthread_create(&tid, 0, myfunc, &start); // ERROR!
return tid;
}
위의 코드는 유효한 코드가 아닙니다. 왜냐하면 start_threads가 my func가 시작하기도 전에 return될 것이기 때문입니다. function은 start의 주소를 건네주지만, myfunc가 실행되고 나서 start는 더이상 scope에 존재하지 않고 이 주소는 다른 변수들을 위해 사용되어질 것이기 때문입니다.
다음 코드는 stack 변수의 lifetime이 background thread보다 더 길기 때문에 유효한 코드입니다.
void start_threads() {
int start = 42;
void *result;
pthread_t tid;
pthread_create(&tid, 0, myfunc, &start); // OK - start will be valid!
pthread_join(tid, &result);
}
'Angrave System Programming > Intro to Pthreads' 카테고리의 다른 글
pthreads : Parallel Problems(Bonus) (0) | 2019.01.14 |
---|---|
Pthreads : Usage in Practice(2) (0) | 2019.01.14 |
Pthread Introduction (0) | 2019.01.14 |