Pthread를 이용한 멀티스레드 프로그래밍

Pthread를 이용해서 멀티스레드 프로그래밍이 가능하다.
이번 포스트를 통해서 소개하는 프로그램은 가장 기초적인 멀티스레드 프로그램이다.

Pthread를 통해서 2개의 스레드를 생성하고, 각각의 스레드에는 인자로 2차원 배열을 넘겨줄 것이다.
그러면 각각의 스레드에서는 행우선, 열우선 방식으로 2차원 배열의 값들의 총합을 구하는 간단한 프로그램이다.
코드는 다음과 같다.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *runner_row(void *parameters);
void *runner_column(void *parameters);


typedef struct {
    int **arr;
} parameter_arr;


int main() {
    pthread_t tid[2];
    pthread_attr_t attr;
    parameter_arr *param;
    int **arr;
    int i, j;

    param = (parameter_arr *) malloc(sizeof(parameter_arr));
    if (param == NULL) {
        fprintf(stderr, "Memory allocation error: *param\n");
        return -1;
    }

    arr = (int **) malloc(sizeof(int *) * 5);
    if (arr == NULL) {
        fprintf(stderr, "Memory allocation error: **arr\n");
        return -1;
    }

    for (i = 0; i < 5; i++) {
        arr[i] = (int *) malloc(sizeof(int) * 5);
    }
    for (i = 0; i < 5; i++) {
        if (arr[i] == NULL) {
            fprintf(stderr, "Memory allocation error: *arr\n");
            return -1;
        }
    }

    for (i = 0; i < 5; i++) {
        for (j = 0; j < 5; j++) {
            arr[i][j] = j;
        }
    }

    printf("Array Information\n");
    for (i = 0; i < 5; i++) {
        for (j = 0; j < 5; j++)
            printf("%d ", arr[i][j]);
        printf("\n");
    }
    printf("\n");

    param->arr = arr;

    pthread_attr_init(&attr);

    pthread_create(&tid[0], &attr, runner_row, (void *) param);
    pthread_create(&tid[1], &attr, runner_column, (void *) param);

    for (i = 0; i < 2; i++) {
        pthread_join(tid[i], NULL);
    }

    printf("Main thread is now terminate.\n");

    for (i = 0; i < 5; i++) {
        free(arr[i]);
    }
    free(arr);

    return 0;
}

void *runner_row(void *parameters) {
    int sum = 0;
    int i, j;
    parameter_arr param = *(parameter_arr *) parameters;

    printf("runner_row thread is created\n");

    for (i = 0; i < 5; i++) {
        for (j = 0; j < 5; j++) {
            sum += param.arr[i][j];
        }
    }

    printf("sum of runner_row thread: %d\n", sum);
    printf("runner_row thread is finished!\n");

    pthread_exit(0);
}

void *runner_column(void *parameters) {
    int sum = 0;
    int i, j;
    parameter_arr param = *(parameter_arr *) parameters;

    printf("runner_column thread is created\n");

    for (j = 0; j < 5; j++) {
        for (i = 0; i < 5; i++) {
            sum += param.arr[i][j];
        }
    }

    printf("sum of runner_column thread: %d\n", sum);
    printf("runner_column thread is finished!\n");

    pthread_exit(0);
}

pthread를 사용하기 위해서는 #include <pthread.h> 와 컴파일 시 pthread 링크를 꼭 해주어야 한다.
컴파일 옵션은 다음과 같다.
gcc -o {output} {source} -lpthread

그리고 스레드를 사용하기 위한 변수 선언은 다음과 같다.
pthread_t tid[2] // 2개의 스레드를 사용하기 위해서 배열로 선언하였으며, 스레드 id를 담을 변수.
pthread_attr_t attr // 스레드의 특성을 담을 변수.

이러한 준비가 완료되면,

  1. 위의 변수들 초기화.
  2. 스레드를 생성.
    pthread_create(*스레드id, *attribute, thread함수, (void *)arg);
    의 형태로 선언되어 있다. 레퍼런스는 man pthread_create 를 통해서 확인할 수 있다.
    스레드를 create하는 순간부터 스레드가 작동하게 된다.
  3. 스레드를 생성한 main thread에서는 각각의 스레드의 작업이 끝나기를 기다린다.
    pthread_join(thread_id, (void **)ret_val);
    의 형태로 정의되어 있으며, 스레드의 반환값을 받을 수도 있다. 레퍼런스는 man pthread_join 을 통해서 확인할 수 있다.

이러한 형태로 프로그램이 작동하게 된다.
위 코드의 실행 결과는 다음과 같다.
멀티스레드의 특성답게, 각각의 스레드가 독립적으로 실행되는 것을 확인할 수 있다.
*pthread_create 함수를 통해서 2차원 배열을 파라미터로 넘기기 위해서 구조체를 사용하였다.

댓글 남기기