멀티 쓰레드

이동욱

2021/08/18

Categories: 네트워크

스레드


스레드의 생성


기본적으로 프로그램은 하나의 스레드로 구성되어 있다. 여기에 추가의 작업 흐름을 만들기 위해서는 pthread_create() 함수를 호출하면 된다.

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_r *attr, void *(start_routine)(void *), void *arg);

인자

결과값

데이터, 힙, 스택 그리고 스레드

스레드 예제

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

void *init_thread(void *perm) {
  int i;
  for (i = 1; i < 10; i++) {
    printf("counter: %d\n", i);
    sleep(1);
  }
  printf("thread is now terminated. \n");
}

int main(int argc, char *argv[]) {
  pthread_t thread_id;

  if (pthread_create(&thread_id, NULL, init_thread, NULL) != 0) {
    fprintf(stderr, "pthread creation error\n");
    exit(0);
  }

  sleep(5);
  printf("main function is terminated.\n");
  return 0;
}

int pthread_join(pthread_t thread, void **retval);

인자

결과값

pthread_join() 함수는 실패 시 다음과 같은 에러코드를 반환한다.

예제

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

void *init_thread(void *perm) {
  int i;
  for (i = 0; i < 10; i++) {
    printf("counter: %d\n", i);
    sleep(1);
  }
  printf("thread is now terminated. \n");
}

int main(int argc, char *argv[]) {
  pthread_t thread_id;
  int res;

  if (pthread_create(&thread_id, NULL, init_thread, NULL) != 0) {
    fprintf(stderr, "pthread creation error\n");
    exit(0);
  }

  if (pthread_join(thread_id, (void **)&res) != 0) {
    fprintf(stderr, "pthread join error\n");
    exit(0);
  }
  printf("main function is terminated\n");
  return 0;
}

스레드 사이의 통신

예제

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

#define SEM_NAME "/test"

void *thread_a_main(void *arg);
void *thread_b_main(void *arg);

static sem_t *sem;
static int counter = 0;

int main(int argc, char *argv[]) {
  pthread_t thread_id_1, thread_id_2;
  int res;

  sem = sem_open(SEM_NAME, O_RDWR | O_CREAT, 0777, 1);
  if (sem == SEM_FAILED) {
    fprintf(stderr, "sem open error \n");
    exit(1);
  }

  if (pthread_create(&thread_id_1, NULL, thread_a_main, NULL) != 0) {
    fprintf(stderr, "pthread 1 creation error\n");
    exit(0);
  }

  if (pthread_create(&thread_id_2, NULL, thread_b_main, NULL) != 0) {
    fprintf(stderr, "pthread 2 creation error\n");
    exit(0);
  }

  if (pthread_join(thread_id_1, (void **) &res) != 0) {
    fprintf(stderr, "pthread 1 join error\n");
    exit(0);
  }

  if (pthread_join(thread_id_2, (void **) &res) != 0) {
    fprintf(stderr, "pthread 2 join error\n");
    exit(0);
  }

  sem_unlink(SEM_NAME);
  return 0;
}


void *thread_a_main(void *arg) {
  int i;
  for (i = 0; i < 60000; i++) {
    sem_wait(sem);
    counter += 2;
    printf("thread a increases the counter by 2: counter - %d\n", counter);
    sem_post(sem);
  }
  return NULL;
}

void *thread_b_main(void *arg) {
  int i;
  for (i = 0; i < 60000; i++) {
    sem_wait(sem);
    counter += 3;
    printf("thread b increases the counter by 3: counter - %d \n", counter);
    sem_post(sem);
  }
  return NULL;
}

뮤텍스를 이용한 데이터 동기화


int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

인자

결과값

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destory(pthread_mutex_t *mutex);

인자

예제

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

void *thread_a_main(void *arg);
void *thread_b_main(void *arg);

static int counter = 0;
static pthread_mutex_t mutex;

int main(int argc, char *argv[]) {
  pthread_t thread_id_1, thread_id_2;
  int res;
  pthread_mutex_init(&mutex, NULL);

  pthread_create(&thread_id_1, NULL, thread_a_main, NULL);
  pthread_create(&thread_id_2, NULL, thread_b_main, NULL);

  pthread_join(thread_id_1, (void**) &res);
  pthread_join(thread_id_2, (void**) &res);

  pthread_mutex_destroy(&mutex);
  return 0;
}

void *thread_a_main(void *arg) {
  int i;
  for (i = 0; i < 10000; i++) {
    pthread_mutex_lock(&mutex);
    counter += 2;
    printf("thread a increases the counter by 2: counter - %d\n", counter);
    pthread_mutex_unlock(&mutex);
  }
  return NULL;
}

void *thread_b_main(void *arg) {
  int i;
  for (i = 0; i < 10000; i++) {
    pthread_mutex_lock(&mutex);
    counter += 3;
    printf("thread b increases the counter by 3: counter - %d\n", counter);
    pthread_mutex_unlock(&mutex);
  }
  return NULL;
}

참고 문헌


>> Home