Thread

GAON PARK·2023년 11월 14일
0
post-custom-banner
  • 어떤 프로그램 내에서, 특히 프로세스 내에서 실행되는 흐름의 단위
  • 함수 단위로 구성
  • 동시 동작을 위해 필요한 기법 중 하나

Multi Thread

Thread POSIX API

하나의 프로세스 안에서 여러 스레드를 이용할 수 있도록 운영체제가 지원하는 API

Programming 방식

  • pthread_create(&t1, NULL, func, NULL)
    • 이때 func 는 void* 를 리턴하는 형태
    • return x 는 생략 가능
  • <pthread.h>
    • POSIX Thread
    • 리눅스, Windows 등 어떤 OS든 POSIX를 지원하면, Thread 사용 가능
    • 위치 = /usr/include/pthread.h
    • thread를 사용할 경우 반드시 pthread library를 링킹
      • gcc ./sample.c -o ./gg -lpthread
  • pthread_t : 구조체
    • thread handler
    • thread를 제어하거나 정의할 때 사용
    • 채워 넣어야 할 멤버들은 pthread_create()를 통해 채운다

상세 API는 Thread API 참고

Thread의 메모리 공유

  • .text, .bss, .data, .heap → 공유 가능
  • .stack → 공유 안 됨
#include<stdio.h>
#include<pthread.h>
#include <stdlib.h>

int a = 100; //.data
int b;		 //.bss
void* abc(){
    int c = 10; //stack
    printf("=================\n");
    printf(".data  : 0x%p\n", (void*)&a);
    printf(".bss   : 0x%p\n", (void*)&b);
    printf(".stack : 0x%p\n", (void*)&c);
    printf(".heap  : 0x%p\n", (int*)malloc(4));
    return 0;
}


int main(){
    pthread_t t1, t2;
    pthread_create(&t1, NULL, abc, NULL);
    pthread_create(&t2, NULL, abc, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    return 0;
}

문제점

공유 변수를 각각의 함수가 다르게 조작하여, 원하는 동작이 이루어지지 않을 수 있다

Race Condition

  • thread / process 의 타이밍에 따라 결과 값이 달라질 수 있는 상태
  • 공유 메모리로 인해 결과가 달라질 수 있는 상태

Critical Section

  • 공유되는 메모리로 인해 문제가 생길 수 있는 코드 영역
  • thread / process 가 동시에 접근해서는 안 되는 곳
    • HW 장치를 이용하는 곳
    • shared resource (전역 변수 등)

해결 방법

Thread synchronization

  • race condition 이 발생하지 않도록 예방하기 위한 도구, 기능
  • 다양한 알고리즘
    • [[#Mutex|mutex]]
    • semaphore
    • spinlock
    • barrier 등

Mutex

키를 기반으로 하는 상호 배제 기법

  • 공유 자원에 접근할 때 키를 이용해서 다른 thread/process 의 접근을 막는다
  • critical section 진입 시 잠그고 코드를 수행한 뒤 푼다
  • 동기화 하고자 하는 대상이 1개 일 때 사용한다
#include <stdio.h>
#include <pthread.h>

pthread_mutex_t mlock;
int cnt=0;
void *run(){
	pthread_mutex_lock(&mlock); // 잠그고
	for(int i=0; i<10000; i++) cnt++; // cnt = critical section
	pthread_mutex_unlock(&mlock); // 푼다
}

int main(){
	pthread_mutex_init(&mlock, NULL);
	
	pthread_t tid[4];
	for(int i=0; i<4; i++) pthread_create(&tid[i], NULL, run, NULL);
	for(int i=0; i<4; i++) pthread_join(tid[i], NULL);
	
	printf("%d\n", cnt);
	
	pthread_mutex_destroy(&mlock);

    	return 0;
}

상세 API는 Mutex API 참고

post-custom-banner

0개의 댓글