The fork system call
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
– Return:
• Parent process: the process id of the child process
(non zero)
• Child process: 0
fork() 함수에는 Parent값과 child값이 있다. Parent 값은 child 값을 리턴받는다. child는 0을 받는다.(child인지 식별 목적)
• Programming tip
– Use the return value of the fork system call
if(pid==0){
... /* child process executes here */
} else {
... /* parent process executes here */
}
리턴 값이 0이면 child로 판단해서 child 코드를 실행.
0이 아니라면 parent로 판단하여 parent의 코드를 실행한다.
테스크를 생성하는 예제 프로그램을 통해 확인해보기
/* test_fork2.c: 같은 변수 접근 */
#include <sys/types.h>
#include <unistd.h>
int glob = 6;
char buf[] = "a write to stdout\n";
int main(void){
int var = 88;
pid_t pid;
if (write(STDOUT_FILENO, buf, sizeof(buf )) != sizeof(buf )) {
perror(“write error”); exit(1);
}
printf("before fork\n"); /* we don't flush stdout */
glob(전역변수) 으로 6을, var(지역변수) 값으로 88을 지정했다.
마지막 printf문을 보고 출력 전임을 확인할 수가 있다.
*pid_t는 Process ID의 약자로 프로세스 식별자를 의미한다. fork() 호출에서 사용된다.
/* test_fork2.c: 같은 변수 접근 */
if ( (pid = fork()) < 0) {
perror(“fork error”); exit(1);
} else if (pid == 0) { /* child */
glob++; var++; /* modify variables */
} else
sleep(2); /* parent */
printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
exit(0);
}
fork()값을 받아오는데 0보다 작으면 -> Error
pid가 0이면 -> child process를 진행.
glob = 6, var = 88 값이 존재한다. 이 값을 child에게 카피해준다.
child또한 값을 갖는다. child : glob = 6, var = 88 -> 실행된 코드로 인해 glob = 7, var = 89
나머지는 parent가 실행되는 코드이다.
이후 printf에서는 pid에 child값이 출력되고, glob은 7, var은 89가 나온다.
parent라면 2초후에 pid에 parent값이 출력되고, glob은 6, var은 88 나온다.
Pthread
Pthread는 POSIX Threads의 약자이다. 유닉스 계열 운영체제에서 멀티쓰레딩을 지원하는 표준 API이다.
#include <pthread.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{ printf("Hello World! It’s me, thread #%ld \n", threadid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc, t;
for(t=0;t < NUM_THREADS;t++) {
printf(“In main: creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1);
}
}
pthread_exit(NULL);
}
#define NUM_THREADS 5 는 5개의 쓰레드를 만들겠다는 뜻이다.
pthread_t threads[NUM_THREADS]; 5개의 쓰레드 생성한다.
마지막에 eixt를 사용하면 전체가 종료되지만 prhread_exit를 사용하게 되면 생성된 쓰레드만 종료된다.
예제를 통해 살펴보도록 한다.
#include <pthread.h>
#define NUM_THREADS 5
int glob = 6;
void *PrintHello(void *threadid)
{
int var = 88;
glob++;
var++;
printf("thread #%ld glob = %d, var = %d \n",threadid,
glob, var);
pthread_exit(NULL);
}
5개의 쓰레드를 생성하고 glod(전역변수)에 6 할당한다.
멀티쓰레드는 스택은 공유하지 않지만 데이터 영역은 공유한다. 따라서 glod(전역변수)의 값은 서로 공유한다.
glob의 초기값은 6.
var값은 스택값으로 88이 저장된다.
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc, t;
for(t=0;t < NUM_THREADS;t++) {
printf("In main: creating thread %d\n", t);
rc = pthread_create(&threads[t],NULL,PrintHello,(void *)t);
if (rc) {
printf(“ERR: return code from pthread_create() is %d\n",rc);
exit(-1);
}
}
pthread_exit(NULL);
}
glob++이므로 6에서 7로 변한다.
var값 또한 88에서 89로 변한다.
!!! 두번째 쓰레드가 실행될때 glob의 값은 7에서 8로 변하지만, var은 각각 존재하므로 다시 88에서 89로 변한다.
thread | glob | var |
thread1 | 7 | 89 |
thread2 | 8 | 89 |
thread3 | 9 | 89 |
thread4 | 10 | 89 |
thread5 | 11 | 89 |
'컴퓨터과학 > 운영체제' 카테고리의 다른 글
메모리 관리 (1) | 2024.05.31 |
---|---|
병행성 : 교착상태와 기아 (0) | 2024.05.31 |
운영체제 병행성 : 상호배제와 동기화 (0) | 2024.05.14 |
What is 쓰레드? (0) | 2024.05.06 |
운영체제가 뭔데? 이름부터 어려운게 거부감 드는데? (0) | 2024.05.03 |