๐Ÿ˜Ž ๊ณต๋ถ€ํ•˜๋Š” ์ง•์ง•์•ŒํŒŒ์นด๋Š” ์ฒ˜์Œ์ด์ง€?

[ํ”„๋กœ์„ธ์Šค์™€ ์Šค๋ ˆ๋“œ ๋‹ค์ค‘ ์ฒ˜๋ฆฌ] POSIX ์Šค๋ ˆ๋“œ์™€ ๋™๊ธฐํ™” ๋ณธ๋ฌธ

๐Ÿ‘ฉ‍๐Ÿ’ป IoT (Embedded)/Raspberry Pi

[ํ”„๋กœ์„ธ์Šค์™€ ์Šค๋ ˆ๋“œ ๋‹ค์ค‘ ์ฒ˜๋ฆฌ] POSIX ์Šค๋ ˆ๋“œ์™€ ๋™๊ธฐํ™”

์ง•์ง•์•ŒํŒŒ์นด 2024. 1. 17. 19:16
728x90
๋ฐ˜์‘ํ˜•

<์„œ์˜์ง„ ๋‹˜์˜ ์‚ฌ๋ฌผ์ธํ„ฐ๋„ท์„ ์œ„ํ•œ ๋ฆฌ๋ˆ…์Šค ํ”„๋กœ๊ทธ๋ž˜๋ฐ with ๋ผ์ฆˆ๋ฒ ๋ฆฌํŒŒ์ด ์„œ์ ์„ ์ฐธ๊ณ ํ•ด์„œ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค :-)>

 

โญ POSIX ์Šค๋ ˆ๋“œ

์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ผ์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์—๋Š” ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ด์šฉํ•œ๋‹ค

ํ”„๋กœ์„ธ์Šค๋Š” ์ž์‹ ๋งŒ์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์ƒˆ๋กœ์šด ํ”„๋กœ์„ธ์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ๋งˆ๋‹ค ํ”„๋กœ์„ธ์Šค๋ฅผ ์œ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑํ•˜๋Š” ์ž‘์—…์ด ๋ณต์žกํ•˜๋‹ค

๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ๊ณต์œ ๋˜๋Š” ๋ถ€๋ถ„ ์—†์ด ๋ณ„๋„์˜ ์˜์—ญ์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์ด ๋‚ญ๋น„๋œ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค

 

์Šค๋ ˆ๋“œ(Thread) ๋Š” ํ”„๋กœ์„ธ์Šค์—์„œ ๋‚˜๋ˆ„์–ด์ง€๋Š” ์ผ์˜ ๋‹จ์œ„๋กœ ์ปค๋„ ๋ ˆ๋ฒจ์˜ ์Šค๋ ˆ๋“œ์™€ ์œ ์ € ๋ ˆ๋ฒจ์˜ ์Šค๋ ˆ๋“œ๋กœ ๊ตฌ๋ถ„๋œ๋‹ค

์ผ๋ฐ˜์ ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋Š” ์œ ์ € ๋ ˆ๋ฒจ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์œ ์ € ๋ ˆ๋ฒจ์˜ ์Šค๋ ˆ๋“œ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์™€ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ์ด ๋น ๋ฅด๋ฉฐ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋‚ญ๋น„๋„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค

ํ•˜์ง€๋งŒ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž˜๋ชป ๊ฑด๋“œ๋ฆฌ๋ฉด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์ž‡๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋“ค์—๋„ ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค

 

์Šค๋ ˆ๋“œ ๊ฐ„์—๋Š” ์ „์—ญ ๋ณ€์ˆ˜์™€ ํž™ ๋ฉ”๋ชจ๋ฆฌ, ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋“ฑ์„ ๊ณต์œ ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์Šค์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ช‡ ๊ฐ€์ง€ ์ผ์„ ๋™์‹œ์— ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์Šค๋ ˆ๋“œ ๊ฐ„ ์ฝ˜ํ…์ŠคํŠธ ์Šค์œ„์นญ (Context Switching) ์ด ํ”„๋กœ์„ธ์Šค๋ณด๋‹ค ๋น ๋ฅด๊ณ , ๊ณต์œ ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์„œ ์Šค๋ ˆ๋“œ ๊ฐ„ ํ†ต์‹ ์ด ํ”„๋กœ์„ธ์Šค ๊ฐ„ ํ†ต์‹ ๋ณด๋‹ค ๊ฐ„๋‹จํ•˜๋‹ค

 

โ˜‘๏ธ ์Šค๋ ˆ๋“œ์˜ ์ƒ์„ฑ

์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” pthread_create() ํ•จ์ˆ˜

์Šค๋ ˆ๋“œ๋กœ ํ•˜๊ณ  ์‹ถ์€ ์ผ์„ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋กœ ์ž‘์„ฑํ•œ ํ›„ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•ด์„œ ๋“ฑ๋กํ•˜๊ธฐ

์ฒซ ๋ฒˆ์งธ ์ธ์ž(pthread_t) ๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ ID ๋กœ ๋’ค์˜ ์Šค๋ ˆ๋“œ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ID

๋‘ ๋ฒˆ์งธ ์ธ์ž(attr) ์€ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ํ•„์š”ํ•œ ์†์„ฑ์˜ ๊ฐ’์œผ๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ NULL ์‚ฌ์šฉ

๋ฆฌ๋ˆ…์Šค์—์„œ ์Šค๋ ˆ๋“œ๋Š” ํ•ฉ๋ฅ˜ ๊ฐ€๋Šฅํ•˜๊ณ  ๋น„์‹ค์‹œ๊ฐ„ ์Šค์ผ€์ค„ ์ •์ฑ…์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค

์„ธ ๋ฒˆ์งธ ์ธ์ž(start_rountine) ๋Š” ์Šค๋ ˆ๋“œ๋กœ ํ•ด์•ผ ํ•  ์ผ์„ ์ •์˜ํ•ด๋†’์€ ํ•จ์ˆ˜

์ผ๋ฐ˜์ ์œผ๋กœ while, for ๋ฃจํ”„๋กœ ์›ํ•˜๋Š” ์ผ์„ ๊ณ„์†ํ•ด์„œ ์‹คํ–‰ํ•˜๋„๋ก ํ•œ๋‹ค

๋„ค ๋ฒˆ์งธ ์ธ์ž(arg) ๋Š” ์„ธ ๋ฒˆ์งธ ์ธ์ž์—์„œ ์‚ฌ์šฉํ•œ start_routine ํ•จ์ˆ˜๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฐ’์ด๋‹ค

 

์ด ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ์— ์„ฑ๊ณตํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ ์ธ์ž์— pthread_t ํ˜•์˜ ํ˜„์žฌ์˜ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•œ ID ๋ฅผ ์„ค์ •ํ•˜๊ณ  0 ๋ฐ˜ํ™˜

ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑํ•œ ํ›„ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋Œ€๊ธฐํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์Šค๋ ˆ๋“œ๋„ ์ข…๋ฃŒํ•ด์•ผํ•  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•ด์•ผ ํ•œ๋‹ค

์„œ๋ธŒ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰๋˜๊ณ  ์žˆ์„ ๋•Œ๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋•Œ pthread_join() ํ•จ์ˆ˜ ์‚ฌ์šฉํ•œ๋‹ค

์ฒซ ๋ฒˆ์งธ ์ธ์ž๋กœ pthread_create() ์—์„œ ์„ค์ •๋œ ์Šค๋ ˆ๋“œ์˜ ID

๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ์Šค๋ ˆ๋“œ๋ฅผ ๋™์ž‘ํ•˜๋Š” ํ•จ์ˆ˜(start_routine) ์—์„œ ๋ฐ˜ํ™˜๋˜๋Š” ๊ฐ’์„ ๋ฐ›๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค

 

main() ํ•จ์ˆ˜๋กœ ์‹œ์ž‘๋˜๋Š” ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์„œ๋ธŒ ์Šค๋ ˆ๋“œ๋“ค๋„ ํ•จ๊ป˜ ์ข…๋ฃŒ๋œ๋‹ค

๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ pthread_create() ๋ฅผ ์ด์šฉํ•ด ์ƒ์„ฑ๋œ ์Šค๋ ˆ๋“œ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— pthread_detach() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

๋ถ„๋ฆฌ๋œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๊ฒฝ์šฐ pthread_join() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„๋„ ๋ชจ๋“  ์ž์›์„ ํ•ด์ œํ•œ๋‹ค

 

์Šค๋ ˆ๋“œ๋ฅผ ์ข…๋ฃŒํ•˜๊ฑฐ๋‚˜ ์ทจ์†Œํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ๋„ค๋Š” pthread_exit() ํ•จ์ˆ˜๋‚˜ pthread_cancle() ํ•จ์ˆ˜ ์‚ฌ์šฉ

์Šค๋ ˆ๋“œ ์ž์‹ ์— ๋Œ€ํ•œ ID ๋ฅผ ์•Œ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— pthread_self() ํ•จ์ˆ˜ ์‚ฌ์šฉ

// ๊ฐ„๋‹จํ•œ ์Šค๋ ˆ๋“œ (posix ์„ธ๋งˆํฌ์–ด ํ•จ์ˆ˜๋ฅผ ์Šค๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๋ณ€๊ฒฝํ•˜๊ธฐ)
#include <stdio.h> 		/* printf() ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ํ—ค๋” ํŒŒ์ผ */
#include <unistd.h>
#include <fcntl.h> 		/* O_CREAT, O_EXEC ๋งคํฌ๋กœ๋ฅผ ์œ„ํ•œ ํ—ค๋” ํŒŒ์ผ */
#include <pthread.h>
#include <semaphore.h> 		/* sem_open(), sem_destroy(), sem_wait() ๋“ฑ ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ํ—ค๋” ํŒŒ์ผ */

sem_t *sem; 			/* ์„ธ๋งˆํฌ์–ด๋ฅผ ์œ„ํ•œ ์ „์—ญ ๋ณ€์ˆ˜ */
static int cnt = 0; 		/* ์„ธ๋งˆํฌ์–ด์—์„œ ์‚ฌ์šฉํ•  ์ž„๊ณ„ ๊ตฌ์—ญ ๋ณ€์ˆ˜ */

void p() 			/* ์„ธ๋งˆํฌ์–ด์˜ P ์—ฐ์‚ฐ */
{
    sem_post(sem);
}

void v() 			/* ์„ธ๋งˆํฌ์–ด์˜ V ์—ฐ์‚ฐ */
{
    sem_wait(sem);
}

void *ptheadV(void *arg) 	/* V ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. */
{
    int i;

    for(i = 0; i < 10; i++) {
        if(cnt >= 7) usleep(100); 	/* 7 ์ด์ƒ์ด๋ฉด 100๋ฐ€๋ฆฌ์ดˆ ๋™์•ˆ ๋Œ€๊ธฐํ•œ๋‹ค. */
        cnt++;
        printf("increase : %d\n", cnt) ;
        fflush(NULL);
        v();
    }

    return NULL;
}

void *ptheadP(void *arg) 	/* P ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. */
{
    int i;

    for(i = 0; i < 10; i++) {
        p(); 			/* ์„ธ๋งˆํฌ์–ด๊ฐ€ 0์ด ๋˜๋ฉด ๋ธ”๋ก๋œ๋‹ค. */
        cnt--;
        printf("decrease : %d\n", cnt);
        fflush(NULL);
        usleep(100); 		/* 100๋ฐ€๋ฆฌ์ดˆ ๊ฐ„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค. */
    }

    return NULL;
}

int main(int argc, char **argv)
{
    pthread_t ptV, ptP; 	/* ์Šค๋ ˆ๋“œ๋ฅผ ์œ„ํ•œ ์ž๋ฃŒํ˜• */
    const char* name = "posix_sem";
    unsigned int value = 7; 	/* ์„ธ๋งˆํฌ์–ด์˜ ๊ฐ’ */

    /* ์„ธ๋งˆํฌ์–ด ์—ด๊ธฐ */
    sem = sem_open(name, O_CREAT, S_IRUSR | S_IWUSR, value);
    pthread_create(&ptV, NULL, ptheadV, NULL); 	/* ์Šค๋ ˆ๋“œ ์ƒ์„ฑ */
    pthread_create(&ptP, NULL, ptheadP, NULL);

    pthread_join(ptV, NULL); 	/* ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐ */
    pthread_join(ptP, NULL);

    /* ๋‹ค ์“ด ์„ธ๋งˆํฌ์–ด ๋‹ซ๊ณ  ์ •๋ฆฌ */
    sem_close(sem);
    printf("sem_destroy() : %d\n", sem_destroy(sem));

    /* ์„ธ๋งˆํฌ์–ด ์‚ญ์ œ */
    sem_unlink(name);

    return 0;
}

/*
๋ฉ”์ธ ์Šค๋ ˆ๋“œ ์ด์™ธ์˜ 2๊ฐœ์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ์‹คํ–‰๋œ๋‹ค
์ฒซ ๋ฒˆ์งธ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ  ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๊ณ , ๋‘ ๋ฒˆ์งธ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค๊ณ  ๋‚˜์„œ ๊ฐ’์„ ๊ฐ์†Œ์‹œํ‚จ๋‹ค
์œ„์˜ ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๊ณณ์—์„œ๋Š” 7 ์ด์ƒ์ด๋ฉด 100๋ฐ€๋ฆฌ์ดˆ ๋™์•ˆ ์ •์ง€ํ•˜๊ณ ,
๊ฐ’์„ ๊ฐ์†Œ์‹œํ‚ค๋Š” ๊ณณ์—์„œ๋„ 100๋ฐ€๋ฆฌ์ดˆ ๋™์•ˆ ์ •์ง€ํ•œ๋‹ค

์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ž ์‹œ ์ •์ง€ํ•˜์ง€ ์•Š๊ณ  ๊ณ„์† ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋Šฆ์–ด์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ
usleep() ํ•จ์ˆ˜๋ฅผ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•ด์„œ ์ผ์˜ ์ค‘๊ฐ„์— ์ž ์‹œ ์ •์ง€ํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค

๋นŒ๋“œํ•˜๊ธฐ ์œ„ํ•ด pthread ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งํฌํ•ด์•ผ ํ•œ๋‹ค
gcc๋Š” -pthread๋ฅผ ์ง€์›ํ•˜๊ณ  ์žˆ์ง€๋งŒ, ๋‹ค๋ฅธ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์œ„ํ•ด์„œ -l ์˜ต์…˜ ์ด์šฉํ•ด์„œ pthread ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋งํฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•œ๋‹ค
๋นŒ๋“œ ํ›„ ์‹คํ–‰ํ•ด๋ณด๋ฉด ๊ฐ’์ด ์ฆ๊ฐ€ํ•˜๊ณ  ๋‚œ ์ดํ›„์— ๊ฐ’์ด ๊ณ„์™ํ•ด์„œ ๊ฐ์†Œ๋˜๋Š”๋ฐ ๊ฐ์†Œํ•˜๋Š” ์‹œ์ ์—์„œ ์„ธ๋งˆํฌ์–ด๊ฐ€ 0์ธ ๊ฒฝ์šฐ์—๋Š”
๊ฐ’์ด ์ฆ๊ฐ€๋˜๊ธฐ ์ „๊นŒ์ง€ semop() ํ•จ์ˆ˜์—์„œ ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•œ๋‹ค
์Šค๋ ˆ๋“œ๋Š” ์‹คํ–‰ํ•  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰ ์ˆœ์„œ๊ฐ€ ๋ฐ”๋€” ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฒฐ๊ณผ๊ฐ’์ด ๋‹ค๋ฅด๊ฒŒ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค

gani@gani:~/raspi/Process_Signal $ gcc -o thread thread.c -lpthread
gani@gani:~/raspi/Process_Signal $ ./thread 
*/
gcc -o thread thread.c -lpthread
./thread

 

โญ ๋™๊ธฐํ™”

์Šค๋ ˆ๋“œ๋Š” ํ”„๋กœ์„ธ์Šค์™€ ๋‹ค๋ฅด๊ฒŒ ์Šค๋ ˆ๋“œ ๊ฐ„์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค

์ด๋ฅผ ๊ฒฝ์Ÿ ์กฐ๊ฑด (Race Condition)

ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์—์„œ ์ „์—ญ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ์ ‘๊ทผ์„ ์ œํ•œํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์Šค๋ ˆ๋“œ ๋‚ด์—์„œ ์ž์›์— ๋Œ€ํ•ด ๋ณดํ˜ธ๊ฐ€ ํ•„์š”ํ•œ ๊ตฌ์—ญ์„ ์ž„๊ณ„ ๊ตฌ์—ญ (Critical Section) 

์ œํ•œ๋œ ์ž์›์— ๋Œ€ํ•œ ์ž„์˜์  ์ ‘๊ทผ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š”๋ฐ, ๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‹œ๊ทธ๋„, IPC ๋“ฑ์„ ์ด์šฉํ•œ ํ”„๋กœ์„ธ์Šค ๊ฐ„์˜ ํ†ต์‹ ์„ ์ด์šฉํ•ด์„œ ์ ‘๊ทผ ์ œ์–ด๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค

๋ณดํ†ต ์ž์›์˜ ์ž ๊ธˆ (lock) ์„ ์ด์šฉํ•˜๋Š”๋ฐ ์„ธ๋งˆํฌ์–ด๋‚˜ ๋ฎคํ…์Šค๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

ํ•œ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๋™๊ธฐํ™” (Serialization)

 

โ˜‘๏ธ ๋ฎคํ…์Šค (Mutex)

๋ฎคํ…์Šค๋Š” ์„ธ๋งˆํฌ์–ด์™€ ๊ณต์œ ๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋“ค์˜ ์ ‘๊ทผ์„ ๋ง‰์•„์ค€๋‹ค

์Šค๋ ˆ๋“œ์˜ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค

 

๋ฎคํ…์Šค๋Š” ์Šค๋ ˆ๋“œ๋“ค์ด ์ž„๊ณ„ ์˜์—ญ์— ๋“ค์–ด๊ฐˆ ๋•Œ ๊ฑธ์–ด ์ž ๊ทธ๊ณ  ๋‚˜๊ฐˆ ๋•Œ ํ’€์–ด์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™๊ธฐํ™”๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ, ๋ฎคํ…์Šค๋Š” ์„ธ๋งˆํฌ์–ด์˜ ์ผ์ข…์œผ๋กœ ์ž์›์˜ ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค

๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๊ด€๋ จ ์ดˆ๊ธฐํ™”๊ฐ€ ํ•„์š”ํ•œ๋ฐ pthread_mutex_init() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

 

๋ฎคํ…์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋‚œ ์ดํ›„์— ํ•ด๋‹น ๋ฎคํ…์Šค์— ๋Œ€ํ•œ ID ๊ฐ€ pthread_mutex_t ํ˜•์œผ๋กœ ์„ค์ •๋œ๋‹ค

์ด ๊ฐ’์„ ์ด์šฉํ•ด์„œ ๋ฎคํ…์Šค๋ฅผ ์ž ๊ทธ๊ณ  ํ•ด์ œํ•˜๋ฉด ๋˜๋Š”๋ฐ ์ž ๊ธ€ ๋•Œ๋Š” pthread_mutex_lock() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ

์ž ๊ธˆ์„ ํ•ด์ œํ•  ๋•Œ๋Š” pthread_mutex_unlock() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ

 

pthread_mutex_lock() ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฎคํ…์Šค๋ฅผ ์ด๋ฏธ ์ž ๊ทผ ์ƒํƒœ์—์„œ๋Š” ๊ทธ ์ž ๊ธˆ์ด ํ•ด์ œ๋  ๋•Œ๊นŒ์ง€ ๊ณ„์† ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋Š”๋ฐ, ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ž˜๋ชป๋œ ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฌดํ•œ์ • ๋Œ€๊ธฐํ•˜๊ณ  ์žˆ๋Š” ๋ฌธ์ œ์ ์ด ์žˆ๋‹ค

pthread_mutex_trylock() ํ•จ์ˆ˜๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฎคํ…์Šค๋ฅผ ์ด๋ฏธ ์ž ๊ธˆ ์ƒํƒœ์—์„œ๋Š” ์ž ๊ฒจ์žˆ๋Š”์ง€๋งŒ ํ™•์ธํ•˜๊ณ , ์‹คํ–‰ํ•  ์ˆ˜ ์—†์œผ๋ฉด ๋ธ”๋ก๋˜์ง€ ์•Š๊ณ  ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค

๋‹จ์ˆœํžˆ ๋ฎคํ…์Šค๊ฐ€ ์ž ๊ฒจ์žˆ๋Š”์ง€ ํ™•์ธํ•  ๋•Œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

 

์„ธ๋งˆํฌ์–ด์—์„œ ์ž์›์˜ ์ˆ˜๊ฐ€ ํ•˜๋‚˜์ธ ๊ฒฝ์šฐ๋ฅผ ๋ฐ”์ด๋„ˆ๋ฆฌ ์„ธ๋งˆํฌ์–ด

์ž์›์˜ ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ๋ฅผ ์นด์šดํŒ… (counting) ์„ธ๋งˆํฌ์–ด

 

๋ฌด์กฐ๊ฑด ๋Œ€๊ธฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํŠน์ • ์‹œ๊ฐ„๋งŒ ๋Œ€๊ธฐํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” pthrad_mutex_timedlock() ํ•จ์ˆ˜

pthread_mutex_trylock() ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ๋Š” ๋Œ€๊ธฐํ•˜์ง€ ์•Š๊ณ  ๊ทธ๋ƒฅ ๋„˜์–ด๊ฐ€๊ณ , pthread_mutex_lock() ํ•จ์ˆ˜๋Š” ๊ณ„์† ๋Œ€๊ธฐํ•˜๋Š”๋ฐ ์ผ์ • ์‹œ๊ฐ„ ๋งŒํผ ๋Œ€๊ธฐํ•˜๋ฉด ๋Œ€๊ธฐ ์‚ฌํ•ญ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๋ณด๋‹ค ์œ ์—ฐํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•œ๋‹ค

๋ฎคํ…์Šค์˜ ์‚ฌ์šฉ์ด ๋‹ค ๋๋‚˜๋ฉด pthread_mutex_destory() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ๋ฎคํ…์Šค๋ฅผ ํ•ด์ œํ•œ๋‹ค

// ๋ฎคํ…์Šค๋กœ ๋™๊ธฐํ™” ์ด์šฉํ•˜๊ธฐ
#include <stdio.h>
#include <pthread.h>

int g_var = 1;
pthread_mutex_t mid;

void *inc_function(void *);
void *dec_function(void *);

int main(int argc, char **argv)
{
    pthread_t ptInc, ptDec;

    pthread_mutex_init(&mid, NULL); 	/* ๋ฎคํ…์Šค ์ดˆ๊ธฐํ™” */

    pthread_create(&ptInc, NULL, inc_function, NULL);

    pthread_create(&ptDec, NULL, dec_function, NULL);
    pthread_join(ptInc, NULL);
    pthread_join(ptDec, NULL);

    pthread_mutex_destroy(&mid); 	/* ๋ฎคํ…์Šค ์‚ญ์ œ */

    return 0;
}

void *inc_function(void *arg)
{
    pthread_mutex_lock(&mid); 		/* ์ž„๊ณ„ ๊ตฌ์—ญ ์„ค์ • */
    printf("Inc : %d < Before\n", g_var);
    g_var++;
    printf("Inc : %d > After\n", g_var);
    pthread_mutex_unlock(&mid); 	/* ์ž„๊ณ„ ๊ตฌ์—ญ ํ•ด์ œ */

    return NULL;
}

void *dec_function(void *arg)
{
    pthread_mutex_lock(&mid); 		/* ์ž„๊ณ„ ๊ตฌ์—ญ ์„ค์ • */
    printf("Dec : %d < Before\n", g_var);
    g_var--;
    printf("Dec : %d > After\n", g_var);
    pthread_mutex_unlock(&mid); 	/* ์ž„๊ณ„ ๊ตฌ์—ญ ํ•ด์ œ */

    return NULL;
}

/*
๋ฎคํ…์Šค๋ฅผ 2๊ฐœ์˜ ์Šค๋ ˆ๋“œ์—์„œ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์„ ์–ธ
pthread_mutex_init() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ์ดˆ๊ธฐํ™” ํ›„ ์‚ฌ์šฉ์ด ๊ธ‘๋‚˜๋ฉด
pthread_mutex_destory() ํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์„œ ํ•ด์ œํ•œ๋‹ค

๋ฎคํ…์Šค์˜ ์ดˆ๊ธฐํ™”๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด 2๊ฐœ์˜ ์Šค๋ ˆ๋“œ ํ•จ์ˆ˜์—์„œ ์ž„๊ณ„ ๊ตฌ์—ญ (๊ฐ’์„ ์ถœ๋ ฅํ•œ ํ›„ ๊ฐ’์„ ๋ณ€ํ™”์‹œํ‚ค๊ณ  ๋‹ค์‹œ ๋ณ€๊ฒฝ๋œ ๊ฐ’์„ ์ถœ๋ ฅ) ์˜†์—
pthread_mutex_lock() ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ๋’ท๋ถ€๋ถ„์— pthread_mutex_unlock() ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ณดํ˜ธํ•˜๋„๋ก ํ•œ๋‹ค

์ฆ๊ฐ€ ๋ถ€๋ถ„์˜ ์ฝ”๋“œ๊ฐ€ ์™„๋ฃŒ๋˜๊ณ  ๋‚œ ์ดํ›„์— ๊ฐ์†Œ ๋ถ€๋ถ„์ด ์‹คํ–‰๋˜๊ฑฐ๋‚˜
๋ฐ˜๋Œ€๋กœ ๊ฐ์ˆ˜ ๋ถ€๋ถ„์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋œ ์ดํ›„์— ์ฆ๊ฐ€ ๋ถ€๋ถ„์ด ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•œ๋‹ค

gani@gani:~/raspi/Process_Signal $ gcc -o thread_mutex thread_mutex.c -lpthread
gani@gani:~/raspi/Process_Signal $ ./thread_mutex 
*/
gcc -o thread_mutex thread_mutex.c -lpthread
./thread_mutex

 

POSIX ์—์„œ ๊ธฐ๋ณธ์ ์ธ ๋ฎคํ…์Šค ์ด์™ธ์—๋„ ์ฝ๊ธฐ, ์“ฐ๊ธฐ, ์ž ๊ธˆ๋„ ์ง€์›ํ•œ๋‹ค

๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ํ•„์š”์—†๋Š” ๊ฒฝ์šฐ์— ์ฝ๊ธฐ ์ž ๊ธˆ (Read Lock) ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๋ฐ์ดํ„ฐ์˜ ์“ฐ๊ธฐ๊ฐ€ ํ•„์š” ์—†๋Š” ๊ฒฝ์šฐ ์“ฐ๊ธฐ ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

 

โ˜‘๏ธ ์Šค๋ ˆ๋“œ์™€ ์‹œ๊ทธ๋„

์‹œ๊ทธ๋„์€ ์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ณต์œ ๋œ๋‹ค

ํŠน์ • ์‹œ๊ทธ๋„์ด ๋ฐœ์ƒํ•˜๋ฉด ํ”„๋กœ์„ธ์Šค์˜ ๋ชจ๋“  ์Šค๋ ˆ๋“œ์— ์ „๋‹ฌ๋˜๋Š”๋ฐ, ์ด๋•Œ ์Šค๋ ˆ๋“œ์— ์ „๋‹ฌ๋˜๋Š” ์‹œ๊ทธ๋„์„ ์กฐ์ •ํ•˜๊ณ  ์‹ถ์œผ๋ฉด pthread_sigmask() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

int pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask);

sigset_t ํƒ€์ž…์œผ๋กœ ์‹œ๊ทธ๋„ ๋งˆ์Šคํฌ๋ฅผ ์ƒ์„ฑํ•œ ํ›„ pthread_sigmask() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ์„ค์ •ํ•œ๋‹ค

pthread_sigmask() ํ•จ์ˆ˜๋Š” ํ˜„์žฌ์˜ ์Šค๋ ˆ๋“œ์— ์ฒซ ๋ฒˆ์งธ ์ธ์ž (how) ์™€ ๋‘ ๋ฒˆ์งธ ์ธ์ž (newmask) ๋ฅผ ์ด์šฉํ•ด์„œ ์‹œ๊ทธ๋„ ๋งˆ์Šคํฌ๋ฅผ ์„ค์ •ํ•œ๋‹ค

how ๋Š” SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASK ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, SIG_BLOCK ๋Š” ํ˜„์žฌ ์„ค์ •๋œ ์‹œ๊ทธ๋„ ๋งˆ์Šคํฌ์— newmask ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉฐ SIG_UNBLOCK ๋Š” ํ˜„์žฌ ์„ค์ •๋œ ์‹œ๊ทธ๋„ ๋งˆ์Šคํฌ์—์„œ newmask ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  SIG_SETMASK ๋Š” newmask ๋กœ ํ˜„์žฌ ์‹œ๊ทธ๋„ ๋งˆ์Šคํฌ๋ฅผ ์„ค์ •ํ•œ๋‹ค

 

 

728x90
๋ฐ˜์‘ํ˜•
Comments