리눅스 커널 스터디 2주차

이동욱

2022/05/14

프로세스와 쓰레드의 생성과 수행


프로세스

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

int g = 2;

int main() {
    pid_t pid;
    int i = 3;

    printf("PID(%d): parent g=%d, l=%d\n", getpid(), g, i);

    if ((pid = fork()) < 0) {
        perror("fork error");
        exit(1);
    } else if (pid == 0) {
        g++;
        i++;
    } else {
        wait();
    }
    printf("PID(%d): parent g=%d, l=%d\n", getpid(), g, i);
    return 0;
}

쓰레드

#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>

int g = 2;

int sub_func(void *arg)
{
    g++;
    printf("PID(%d): child=%d\n", getpid(), g);
    sleep(2);
    return 0;
}

int main() {
    int pid;
    int child_stack[4096];
    int l = 3;
    printf("PID(%d) : parent g=%d, l=%d\n", getpid(), g, l);
    clone(sub_func, (void *)(child_stack + 4095), CLONE_VM | CLONE_THREAD | CLONE_SIGHAND, NULL);
    sleep(1);
    printf("PID(%d) : parent g=%d, l=%d\n", getpid(), g, l);
    return 0;
}

프로세스의 수행


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

int main() {
    pid_t pid;

    int exit_status;

    if ((pid = fork()) < 0) {
        perror("fork error");
        exit(1);
    } else if (pid == 0) {
        printf("before exec\n");
        execl("./fork", "fork", (char *)0);
        printf("after exec\n");
    } else {
        pid = wait(&exit_status);
    }
    printf("parent\n");
    return 0;
}

리눅스의 태스크 모델


예제


#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/unistd.h>

int main() {
    int pid;

    printf("before fork\n");

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-2);
    } else if (pid == 0) {
        printf("TGID(%d), PID(%ld): child \n", getpid(), syscall(__NR_gettid));
    } else {
        printf("TGID(%d), PID(%ld): parent \n", getpid(), syscall(__NR_gettid));
        sleep(2);
    }
    printf("after fork\n");

    return 0;
}

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/unistd.h>

int main() {
    int pid;

    printf("before fork\n");

    if ((pid = vfork()) < 0) {
        printf("fork error\n");
        exit(-2);
    } else if (pid == 0) {
        printf("TGID(%d), PID(%ld): child \n", getpid(), syscall(__NR_gettid));
        _exit(0);
    } else {
        printf("TGID(%d), PID(%ld): parent \n", getpid(), syscall(__NR_gettid));
        sleep(2);
    }
    printf("after fork\n");

    return 0;
}

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

void *t_function(void *data) {
    int id;
    int i = 0;
    pthread_t t_id;
    id = *((int *) data);
    printf("TGID (%d), PID(%d), pthread_self(%d) : child \n", getpid(), syscall(__NR_gettid), pthread_self());
    sleep(2);
}

int main() {
    int pid, status;
    int a = 1;
    int b = 2;
    pthread_t p_thread[2];
    printf("before pthread_create \n");
    if ((pid = pthread_create(&p_thread[0], NULL, t_function, (void *)&a)) < 0) {
        perror("thread create error: ");
        exit(1);
    }

    if ((pid = pthread_create(&p_thread[1], NULL, t_function, (void *)&b)) < 0) {
        perror("thread create error: ");
        exit(2);
    }
    pthread_join(p_thread[0], (void **)&status);
    printf("pthread_join(%d)\n", status);
    pthread_join(p_thread[1], (void **)&status);
    printf("pthread_join(%d)\n", status);
    printf("TGID(%d), PID(%d) : parent\n", getpid(), syscall(__NR_gettid));
    return 0;
}
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/unistd.h>
#include <sched.h>

int sub_func(void *arg)
{
    printf("TGID(%d), PID(%d): child \n", getpid(), syscall(__NR_gettid));
    sleep(2);
    return 0;
}

int main() {
    int pid;
    int child_a_stack[4096], child_b_stack[4096];

    printf("before clone \n\n");
    printf("TGID(%d), PID(%d) : parent \n", getpid(), syscall(__NR_gettid));

    clone(sub_func, (void *)(child_a_stack + 4095), CLONE_CHILD_CLEARTID | CLONE_CHILD_SETTID, NULL);
    clone(sub_func, (void *)(child_b_stack + 4095), CLONE_VM | CLONE_THREAD | CLONE_SIGHAND, NULL);

    sleep(1);

    printf("after clone \n\n");
    return 0;
}

참고 문헌


>> Home