๐ ๊ณต๋ถํ๋ ์ง์ง์ํ์นด๋ ์ฒ์์ด์ง?
[ํ๋ก์ธ์ค์ ์ค๋ ๋ ๋ค์ค ์ฒ๋ฆฌ] POSIX ์ค๋ ๋์ ๋๊ธฐํ ๋ณธ๋ฌธ
[ํ๋ก์ธ์ค์ ์ค๋ ๋ ๋ค์ค ์ฒ๋ฆฌ] POSIX ์ค๋ ๋์ ๋๊ธฐํ
์ง์ง์ํ์นด 2024. 1. 17. 19:16<์์์ง ๋์ ์ฌ๋ฌผ์ธํฐ๋ท์ ์ํ ๋ฆฌ๋ ์ค ํ๋ก๊ทธ๋๋ฐ 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 ๋ก ํ์ฌ ์๊ทธ๋ ๋ง์คํฌ๋ฅผ ์ค์ ํ๋ค