IPC

IPC (Inter Process Communicatrion) Signal Signal์€ ํ”„๋กœ์„ธ์Šค๊ฐ„ ๋™๊ธฐํ™”๋ฅผ ์œ„ํ•ด ํ”„๋กœ์„ธ์Šค๊ฐ„ ์ „์†กํ•˜๋Š” ์‹ ํ˜ธ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. Software Interrupt ๋ผ๊ณ ๋„ ํ•œ๋‹ค. ์ปค๋„์—์„œ kill -<SIGNAL_NUMBER> <PROCESS_ID> ๋ช…๋ น์œผ๋กœ ํŠน์ • PROCESS_ID์— ISGNAL_NUMBER์— ํ•ด๋‹นํ•˜๋Š” signal์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. signal์€ ์ด 64๊นŒ์ง€ ์ •์˜๋˜์–ด ์žˆ๊ณ  131๊นŒ์ง€๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” signal์ด๋‹ค. 3463์€ ๊ณ ์„ฑ๋Šฅ ๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ์œ„ํ•œ ์‹œ๊ทธ๋„์ด๋‹ค. (32, 33๋Š” ๋ฏธ์ •์˜) kill -l ๋ช…๋ น์œผ๋กœ signal ๋ฆฌ์ŠคํŠธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. SIGHUP SIGINT : ์ธํ„ฐ๋ŸฝํŠธ, Ctrl+C ๋ช…๋ น์œผ๋กœ ์ „์†ก ๊ฐ€๋Šฅ SIGQUIT Coredump์‹œ ๋ฐœ์ƒ SIGILL : Illegal instruction SIGTRAP : debugger is tracing SIGABRT : Abort process SIGBUS : bus error SIGFPE : Floating point exception SIGKILL : ๊ฐ•์ œ ์ข…๋ฃŒ SIGUSR1 : User-defined signal 1, ๋งˆ์Œ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ SIGSEGV : invalid virtual memory reference SIGUSR2 : User-defined signal 2, ๋งˆ์Œ๋Œ€๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ SIGPIPE : ๋ฐ˜๋Œ€ํŽธ์ด ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ pip์— ์‹ ํ˜ธ ์ „์†ก์‹œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ SIGALRM : alarm() ํ•จ์ˆ˜์— ์˜ํ•ด ๋ฐœ์ƒํ•œ ์‹œ๊ทธ๋„ 1 SIGTERM : ์ข…๋ฃŒ ์š”์ฒญ, SIGKILL(9)๋ณด๋‹ค ์•ˆ์ „ํ•œ ์ข…๋ฃŒ ๋ฐฉ๋ฒ•, SIGINT์™€ ์œ ์‚ฌํ•œ ์„ฑ๋Šฅ SIGSTKFLT : Stack fault SIGCHLD : ์ž์‹ process๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ ๋ถ€๋ชจ์—๊ฒŒ ์ „๋‹ฌํ•˜๋Š” ์‹ ํ˜ธ SIGCONT : SIGSTOP ์— ์˜ํ•ด ์ •์ง€๋œ ๊ฒฝ์šฐ, ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ผ๋Š” ์‹ ํ˜ธ SIGSTOP : process ์ •์ง€ SIGTSTP : process ์ผ์‹œ์ •์ง€, Ctrl+Z ๋ช…๋ น์œผ๋กœ ์ „์†ก ๊ฐ€๋Šฅ SIGTTIN : background ์— ์žˆ์„ ๋•Œ read ์š”์ฒญ์„ ๋ฐ›์€ ๊ฒฝ์šฐ ๋ฐœ์ƒ SIGTTOU : background ์— ์žˆ์„ ๋•Œ write ์š”์ฒญ์„ ๋ฐ›์€ ๊ฒฝ์šฐ ๋ฐœ์ƒ SIGURG : ๊ธด๊ธ‰ ํ†ต์‹ ์„ ๋ฐ›์€ ๊ฒฝ์šฐ (Out Of Band) SIGXCPU : ์„ค์ •๋œ CPU ์‚ฌ์šฉ๋Ÿ‰์„ ์ดˆ๊ณผํ•˜์—ฌ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋™์ž‘ ํ•œ ๊ฒฝ์šฐ SIGXFSZ : ํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ ํ—ˆ์šฉ๋œ ํฌ๊ธฐ๋ฅผ ์ดˆ๊ณผํ•œ ๊ฒฝ์šฐ SIGVTALRM : ํ”„๋กœ์„ธ์Šค ์‹คํ–‰์‹œ๊ฐ„ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์‹œ๊ทธ๋„1 SIGPROF : ํ”„๋กœ์„ธ์Šค ์‹คํ–‰์‹œ๊ฐ„ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ์‹œ๊ทธ๋„2 SIGWINCH : Window change SIGIO, SIGPOLL : Input/output is now possible SIGPWR, SIGLOST : Power failure SIGUNUSED, SIGSYS : Unused signal. Signal Library in C signal.h ์— ์ •์˜๋œ signal ํ•จ์ˆ˜๋กœ signal์„ ๋ฌด์‹œ(ignore)ํ•˜๊ฑฐ๋‚˜, ์‹œ๊ทธ๋„ ๋ฐœ์ƒ์‹œ ํŠน์ • ํ•จ์ˆ˜๋ฅผ ๋™์ž‘(catch)์‹œํ‚ค๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ (ignore ๋˜๋Š” catch ์ฒ˜๋ฆฌ) signal์„ ๋ฐ›์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•ด๋‹น ํ”„๋กœ์„ธ์Šค๋Š” ์ข…๋ฃŒํ•œ๋‹ค. SIGKILL(๊ฐ•์ œ์ข…๋ฃŒ ์šฉ๋„)๊ณผ SIGSTOP(๋””๋ฒ„๊น…์‹œ ์ผ์‹œ์ •์ง€ ์šฉ๋„)์‹œ๊ทธ๋„์„ ์ œ์™ธํ•œ ๋ชจ๋“  ์‹œ๊ทธ๋„์„ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๋‹ค. signal(SIGNAL, PID) pid > 0 : PID์— SIGNAL ์ „๋‹ฌ pid < 0 : PID์˜ ์ ˆ๋Œ“๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” groupId๋ฅผ ๊ฐ€์ง„ ํ”„๋กœ์„ธ์Šค๋“ค์— SIGNAL ์ „๋‹ฌ pid == 0 : ์ž์‹ ๊ณผ ๊ฐ™์€ groupId๋ฅผ ๊ฐ€์ง„ ํ”„๋กœ์„ธ์Šค๋“ค์— SIGNAL ์ „๋‹ฌ alarm(TIME) : TIME์ดˆ ์ดํ›„ SIGALRM ์‹œ๊ทธ๋„ ๋ฐœ์ƒ alarm timer๊ฐ€ ๋งŒ๊ธฐ๋˜๊ธฐ ์ „ ์ƒˆ๋กœ์šด alarm์„ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ’์„ ๋ฎ์–ด์“ด๋‹ค. ๋Œ€์‹  alarm ํ•จ์ˆ˜๋Š” ๋‚จ์€ ์‹œ๊ฐ„์„ ๋ฐ˜ํ™˜ ํ•œ๋‹ค. alarm(0) ์„ ํ˜ธ์ถœํ•˜๋ฉด ์•Œ๋ฆผ์ด ์ทจ์†Œ๋œ๋‹ค. ์‹œ๊ทธ๋„ ์ฒ˜๋ฆฌ flag๋Š” bit์—ฐ์‚ฐ์œผ๋กœ ๊ด€๋ฆฌ๋œ๋‹ค. sigset_t ํƒ€์ž…์˜ bit ํ•˜๋‚˜ํ•˜๋‚˜๋“ค์€ 1~64๊นŒ์ง€์˜ signal์„ ์˜๋ฏธํ•˜๊ณ , ์•„๋ž˜์™€ ๊ฐ™์ด set์„ ์—ฐ์‚ฐํ•˜์—ฌ process์—์„œ signal์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. sigemptyset(siget_t* SET) : SET ๋ชจ๋“  ๋น„ํŠธ๋ฅผ 0์œผ๋กœ ์„ธํŒ…. sigfillset(int SIGNAL, sigset_t* SET) : | ์—ฐ์‚ฐ์œผ๋กœ SET ์—์„œ SIGNAL์— ํ•ด๋‹นํ•˜๋Š” ๋น„ํŠธ๋งŒ 1๋กœ ์„ธํŒ… sigdelset(int SIGNAL, sigset_t* SET) : & ์—ฐ์‚ฐ์œผ๋กœ SIGNAL์— ํ•ด๋‹นํ•˜๋Š” ๋น„ํŠธ๋งŒ 0์œผ๋กœ ์„ธํŒ… sigismember(int SIGNAL, sigset_t* SET) : SET์—์„œ SIGNAL๋น„ํŠธ๊ฐ€ 1๋กœ ์„ธํŒ…๋˜์—ˆ๋‹ค๋ฉด true ๋ฐ˜ํ™˜ sigprocmask(int HOW, siget_t* NEW, sigset_t* OLD) : ํŠน์ • SIGNAL์„ ๋ฌด์‹œํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•„์š”ํ•  ๊ฒฝ์šฐ OLD์— siget_t* ํƒ€์ž… ๋ณ€์ˆ˜๋ฅผ ์ง‘์–ด๋„ฃ์œผ๋ฉด ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค์— ์„ค์ •๋œ set์„ ๋‹ด์•„๋‚ธ๋‹ค. SIG_BLOCK : NEW์— set๋œ signal๋“ค์„ ์ถ”๊ฐ€๋กœ ๋ฌด์‹œํ•œ๋‹ค. SIG_UNBLOCK : NEW์— set ๋œ signal๋“ค์˜ ๋ฌด์‹œ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ œํ•œ๋‹ค. SIG_SETMASK : ๊ธฐ์กด ๊ฐ’์— ์ƒ๊ด€์—†์ด NEW์— set ๋œ signal๋“ค๋งŒ ๋ฌด์‹œํ•˜๋„๋ก set์„ ๋ฎ์–ด์“ด๋‹ค. signal ์„ ์ฒ˜๋ฆฌํ•˜์—ฌ signal์— ์˜ํ•ด process๊ฐ€ ์ •์ง€๋˜์ง€ ์•Š๋Š” ๊ตฌ๊ฐ„์„ ์ž„๊ณ„์˜์—ญ ์ด๋ผ ํ•œ๋‹ค. Pipe ํ”„๋กœ์„ธ์Šค๊ฐ„ ๋‹จ๋ฐฉํ–ฅ ํ†ต์‹ ์„ ์œ„ํ•ด ํ”„๋กœ์„ธ์Šค๋“ค์˜ ํ‘œ์ค€ ์ž…์ถœ๋ ฅ์„ ์„œ๋กœ ๊ต์ฐจํ•˜์—ฌ ์—ฐ๊ฒฐํ•˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ„ ๋ฐ์ดํ„ฐ ์ „์†ก์‹œ ์ฃผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. flow control์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋œ๋‹ค. Pipe Library in C pipe(int[2] fd) : ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋‘๊ฐœ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ๋‹จ๋ฐฉํ–ฅ ํ†ต์‹ ์„ ์ƒ์„ฑํ•จ ...

<span title='2023-07-27 20:37:08 +0900 KST'>July 27, 2023</span>&nbsp;ยท&nbsp;8 min&nbsp;ยท&nbsp;AswinBlue

Thread

Thread thread๋Š” process์˜ ๊ฒฝ๋Ÿ‰ํ™” ๋ฒ„์ „์œผ๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค. pthread_create() ํ•จ์ˆ˜๋กœ fork ๋ช…๋ น์„ ๋Œ€์ฒดํ•˜๊ณ , pthread_join() ์œผ๋กœ wait ๋ช…๋ น์„ ๋Œ€์ฒดํ•˜๋ฉด process ๋Œ€์‹  thread๋ฅผ ๋™์ž‘์‹œํ‚จ๋‹ค. thread๋Š” ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฒƒ์ด ๊ธฐ๋ณธ์ด๋ฉฐ, ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰์‹œํ‚ฌ ๋•Œ ๋„ฃ์„ ์ธ์ž์™€, ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด๊ฐ’์„ ๋ฐ›์„ ์ธ์ž๋ฅผ pthread_create์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฐ›๋Š”๋‹ค. ๋ฆฌ๋ˆ…์Šค ํ”„๋กœ์„ธ์Šค ํ‘œ์‹œ ๋ชฉ๋ก์— LWP(light-weight-process) ํ•ญ๋ชฉ์œผ๋กœ ํ‘œ์‹œ๋˜๋ฉฐ, proces ID๊ฐ€ ๊ฐ™๋”๋ผ๋„ LWP ID๊ฐ€ ๋‹ค๋ฅด๋ฉด ๊ฐ™์€ process ์•ˆ์˜ thread์ธ ๊ฒƒ. pthread_exit() ๋กœ thread๋งŒ ์ข…๋ฃŒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. main process๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ๋”ธ๋ ค์žˆ๋Š” thread๋“ค๋„ ํ•จ๊ป˜ ์ข…๋ฃŒ๋œ๋‹ค. ๋‹ค๋งŒ, main thread๋งŒ pthread_exit์œผ๋กœ ์ข…๋ฃŒ์‹œํ‚ค๋ฉด process๊ฐ€ ์ข…๋ฃŒ๋˜์ง€ ์•Š๊ณ  main thread๋งŒ ์ข…๋ฃŒ๋˜๊ณ  ๋‹ค๋ฅธ thread๋“ค์€ ๊ณ„์† ๊ตฌ๋™๋˜๋Š” ํ˜•ํƒœ๊ฐ€ ๋˜๋ฏ€๋กœ ์ฃผ์˜ํ•œ๋‹ค. int pthread_join(pthread_t thread, void **retval) : ์ž์‹ thread๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๊ณ , ์ข…๋ฃŒ์ฒ˜๋ฆฌ๋ฅผ ํ•ด ์ฃผ๋Š” ํ•จ์ˆ˜, pthread_exit()์—์„œ ๋ฐ˜ํ™˜๋œ ๊ฐ’์„ retval๋กœ ๋ฐ›์•„์˜ฌ์ˆ˜ ์žˆ๋‹ค. pthread_detach(int tid) : thread id๊ฐ€ tid์— ํ•ด๋‹นํ•˜๋Š” thread๋ฅผ ๋ถ€๋ชจ thread์—์„œ ๋ถ„๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜. ์ดํ›„ ์ข…๋ฃŒ๋˜๊ณ  join ์ฒ˜๋ฆฌ๋ฅผ ๋Œ€๊ธฐํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ free๋จ. int pthread_self() : ์ž์‹ ์˜ thread id ๋ฅผ ํ™•์ธํ• ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜ void* func(void* data) { (struct ARG*) data; ... pthread_detach(pthread_self()); // pthread_join ๋Œ€์‹  ์‚ฌ์šฉ ๊ฐ€๋Šฅ } ... // thread ์ƒ์„ฑ struct ARG *arg; int tid = pthread_create(&thread, 0, func, arg); ... pthread_join(tid, 0); // pthread_detach ๋Œ€์‹  ์‚ฌ์šฉ ๊ฐ€๋Šฅ ... process ์™€ thread ์ฐจ์ด process๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ์ˆœ๊ฐ„ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ„๋ฆฌ๋˜์ง€๋งŒ, thread๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜์—ฌ ์ˆ˜์ •ํ•˜๊ณ  ๋‚˜์„œ๋„ ๊ฐ™์€ ์˜์—ญ์„ ์ฐธ์กฐํ• ์ˆ˜ ์žˆ๋‹ค. (์ „์ฒด ๊ฐ€์ƒ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•œ๋‹ค.) process๋Š” wait ๊ฐ’์˜ ์ธ์ž๋ฅผ ํ™•์ธ ์—๋Ÿฌ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ˜๋ฉด, thread์˜ ์—๋Ÿฌ๋Š” pthread_join์˜ return ๊ฐ’์„ ํ™•์ธํ•œ๋‹ค. (๊ฐ’์ด 0 ์ดˆ๊ณผ์ด๋ฉด ์—๋Ÿฌ๊ฐ€ ๋จ) ์ผ๋ฐ˜์ ์ธ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋Š”, errno.h ํ—ค๋”ํŒŒ์ผ์— errno ๋ผ๋Š” ๋ณ€์ˆ˜๊ฐ€ ์ „์—ญ๋ณ€์ˆ˜๋กœ ์„ ์–ธ๋˜์–ด ์žˆ๊ณ , ํ”„๋กœ์„ธ์Šค๊ฐ€ ์—๋Ÿฌ์— ์˜ํ•ด ์ข…๋ฃŒ๋  ๊ฒฝ์šฐ ์ด ๋ณ€์ˆ˜์— ๊ฐ’์„ ์ฑ„์›Œ๋„ฃ๋Š”๋‹ค. thread๋Š” ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ๊ณต์œ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— errno๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ Mutex ์ „์—ญ๋ณ€์ˆ˜์˜ ์ƒํ˜ธ ์ฐธ์กฐ์— ์˜ํ•ด ๋ฐœ์ƒํ•˜๋Š” race condition ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ• race condition : ๋‘˜ ์ด์ƒ์˜ thread๊ฐ€ ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ์ ‘๊ทผํ•˜๋ ค ์„œ๋กœ ๊ฒฝ์Ÿํ•˜๋Š” ์ƒํ™ฉ pthread.h ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, pthread ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋–„๋ฌธ์— ๋นŒ๋“œ์‹œ ์˜ต์…˜์— -lpthread๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ... pthread_mutex_lock(&mutex); // ์ „์—ญ๋ณ€์ˆ˜ ์ฐธ์กฐ ์˜์—ญ pthread_mutex_unlock(&mutex); mutex๋ฅผ ์‚ฌ์šฉํ•ด ์ž„๊ณ„ ์˜์—ญ(critical section)์— ๋Œ€ํ•ด mutual exclusion ์†์„ฑ์„ ๋ณด์žฅํ•˜์—ฌ ๋™์‹œ ์ ‘์†์— ์˜ํ•œ ์˜ค๋™์ž‘์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค. Mutex ๋‚ด๋ถ€ ๊ตฌ์กฐ C์–ธ์–ด๋กœ๋Š” compare์™€ set์„ atomicํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์—†์–ด mutual exclusion์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์—†๋‹ค. cas(compare and set) ๋ผ๋Š” ์ฝ”๋“œ๋ฅผ ์–ด์…ˆ๋ธ”๋ฆฌ์–ด์—์„œ ์ง€์›ํ•˜๋Š”๋ฐ, compare์™€ set์„ atomicํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ ํ•จ์ˆ˜๋Š” ์–ด์…ˆ๋ธ”๋ฆฌ์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ C์—์„œ cas๋ฅผ ๊ตฌํ˜„ํ•œ ๋‚ด์šฉ์ด๋‹ค. cpu ์นฉ๋งˆ๋‹ค ์ง€์›ํ•˜๋Š” ํ˜•ํƒœ๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Œ์— ์ฃผ์˜ํ•œ๋‹ค. (์•„๋ž˜๋Š” ์ธํ…”์ด ์ œ๊ณตํ•˜๋Š” ํ˜•ํƒœ) typedef int int32_t; int mutex = 0; // ์ดˆ๊ธฐ๊ฐ’ 0 /** * @brief old_value์™€ *ptr์„ ๋น„๊ตํ•˜์—ฌ ๊ฐ™๋‹ค๋ฉด *ptr์— new_value๋ฅผ ๋Œ€์ž…ํ•œ๋‹ค. * mutex lock์˜ ์—ญํ• ์„ ํ•œ๋‹ค. * @return int old_value์™€ *ptr์˜ ๋น„๊ต ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™๋‹ค๋ฉด false๋ฅผ, ๋‹ค๋ฅด๋‹ค๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ */ int __bionic_cmpxchg(int32_t old_value, int32_t new_value, volatile int32_t* ptr) { int 32_t prev; __asm__ __volatile__ ("lock; cmpxchgl %1, %2" : "=a" (prev) : "q" (new_value), "m" (*ptr), "0" (old_value) : "memory"); return prev != old_value; } Spin Lock while๋ฌธ์„ ๋ฐ˜๋ณตํ•˜๋ฉฐ mutex๋ฅผ ๊ณ„์† ์ฒดํฌํ•˜๋Š” ๊ธฐ๋ฒ• void spin_lock(int* mutex) { while (__bionic_cmpxchg(0, 1, mutex)); // mutex๊ฐ€ 0์ด ๋  ๋•Œ ๊นŒ์ง€ ๋ฌดํ•œ ๋Œ€๊ธฐ } CPU ํ™œ์šฉ๋„๊ฐ€ ๋–จ์–ด์ง€๋ฏ€๋กœ ์ž„๊ณ„์˜์—ญ์ด ์งง์€ ๊ฒฝ์šฐ๋งŒ ์‚ฌ์šฉ ๊ถŒ์žฅ Sleep Lock mutex๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ thread๋ฅผ sleep ์‹œํ‚ค๋ฉด thread์— ํ• ๋‹น๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ํ•ด์ œํ•˜์—ฌ ๋‹ค๋ฅธ ๊ณณ์— ํ• ๋‹นํ•ด ์ค„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. gcc์—์„œ๋Š” slelep lock์„ ์ง€์›ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—†์ง€๋งŒ, ์‹œ์Šคํ…œ ์ปค๋งจ๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” futex(fast user mutex)๋ผ๋Š” ํ•จ์ˆ˜๋กœ sleep lock์„ ์ง€์›ํ•œ๋‹ค. C์–ธ์–ด๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์‹œ์Šคํ…œ ์ฝœ๋กœ futex๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. #include <unisted.h> int mutex = 1; void *foo(void *data) { sytstemcall 202, &mutex, 0, 1, 0); // __futex_wait(); ... /* critical section */ systemcall(202, &mutex, 1, 1); // __futex_wake(); } __futex_wait ์€ mutex_lock, __futex_wake๋Š” mutex_unlock์— ๋Œ€์‘๋œ๋‹ค. Self Lock recursive ํ•จ์ˆ˜์—์„œ mutex๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ํ•˜๋‚˜์˜ ํ•จ์ˆ˜์—์„œ ๋™์ผํ•œ mutex๋ฅผ ๋‘๋ฒˆ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋Š” โ€œselfl lock"์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. self lock์ด ๋ฐœ์ƒํ•˜๋ฉด ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ deadlock์ด ๋ฐœ์ƒํ•œ๋‹ค. ์žฌ๊ท€ ํ˜ธ์ถœ์„ ์œ„ํ•œ recursive mutex lock ์ด ์กด์žฌํ•œ๋‹ค. mutex ์ƒ์„ฑ์‹œ attribute๋กœ ์žฌ๊ท€ํ•จ์ˆ˜๋ฅผ ์œ„ํ•œ ์„ค์ •์ด ์กด์žฌํ•˜๋ฉฐ, mutex_lock์„ ํ•œ thread์—์„œ ์ค‘๋ณต ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•˜๋ฉฐ, mutex_lock์„ ํ˜ธ์ถœํ•œ ์ˆ˜๋งŒํผ mutex_unlock์„ ํ˜ธ์ถœํ•ด ์ฃผ๋ฉด mutex๊ฐ€ ํ•ด์ œ๋œ๋‹ค. pthread_mutexattr_t attr; pthread_mutex_t mutex; ... pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutuex_init(&mutex, &attr); ... pthread_mutex_lock(&mutex); // 1 pthread_mutex_lock(&mutex); // 2 pthread_mutex_lock(&mutex); // 3 ... pthread_mutex_unlock(&mutex); // 1 pthread_mutex_unlock(&mutex); // 2 pthread_mutex_unlock(&mutex); // 3 Condition (์กฐ๊ฑด๋ณ€์ˆ˜) thread์—์„œ ์ „์—ญ ๋ณ€์ˆ˜์— ์ฐธ์กฐํ•  ๋•Œ, ์ˆœ์„œ๋ฅผ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ• ์•„๋ž˜ ์ฝ”๋“œ๋Š” thread1์—์„œ ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ thread2์—์„œ ์ „์—ญ๋ณ€์ˆ˜์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค. pthread_cond_t cond = PTHREAD_COND_INITIALIZER; ... thread1() { pthread_mutex_lock(&mutex); // ์ „์—ญ๋ณ€์ˆ˜ ์ฒ˜๋ฆฌ pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); } ... thread2() { pthread_mutex_lock(&mutex); pthread_cond_wait(&cond); // ์ „์—ญ๋ณ€์ˆ˜ ์ฒ˜๋ฆฌ pthread_mutex_unlock(&mutex); } Condition ๋‚ด๋ถ€ ๊ตฌ์กฐ func1() { pthread_mutex_lock(); // <- (1) do_something(); pthread_cond_signal(); pthread_mutex_unlock(); } func2() { pthread_mutex_lock(); pthread_cond_wait(); // <- (2) do_something(); pthread_mutex_unlock(); } func1์ด (1)์—์„œ mutex unlock์„ ๋Œ€๊ธฐํ•˜๊ณ , func2๊ฐ€ (2)์—์„œ condition signal์„ ๋Œ€๊ธฐํ•˜๋ฉด deadlock์ด ๊ฑธ๋ฆด ๊ฒƒ ๊ฐ™์ง€๋งŒ, condition wait์™€ mutex lock์€ ์„œ๋กœ ๊ต์ฐฉ์ƒํƒœ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค. pthread_cond_wait() ์•„๋ž˜์™€ ๊ฐ™์ด mutex_unlock, futex_wait, mutex_lock์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ mutex pthread_cond_wait() { ... pthread_mutex_unlock(); while (condition == 0) // condition ์กฐ๊ฑด์ด ์ถฉ์กฑ๋  ๋•Œ ๊นŒ์ง€ ๋ฌดํ•œ ๋Œ€๊ธฐ { futex_wait(); // sleep lock } condition = 0; // condition ์ดˆ๊ธฐํ™” pthread_mutex_lock(); ... } ์ฆ‰, condition wait๋Š” condition signal์ด ๋ฐœ์ƒํ•œ ์‹œ์ ์ด ์•„๋‹ˆ๋ผ, mutex ๊ฐ€ unlock๋˜๋Š” ์‹œ์ ์— ํƒˆ์ถœ๋œ๋‹ค. Deadlock ๋‘ ๊ฐœ ์ด์ƒ์˜ Mutex๊ฐ€ ์„œ๋กœ ํ•ด์ œ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ ๋Œ€๊ธฐํ•˜์—ฌ ๋” ์ด์ƒ process๊ฐ€ ์ง„ํ–‰๋˜์ง€ ๋ชปํ•˜๊ฒŒ ๋˜๋Š” ์ƒํ™ฉ์„ deadlock์ด๋ผ ํ•œ๋‹ค. lock์„ ์ˆœ์„œ๋Œ€๋กœ ์žก๊ณ , cycle์ด ์ƒ๊ธฐ์ง€ ์•Š๊ฒŒ ๊ด€๋ฆฌํ•˜๋ฉด deadlock์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค. ์žฌ์ง„์ž… ๊ฐ€๋Šฅ ํ•จ์ˆ˜ (Reentrant) thread์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋ฅผ โ€˜์žฌ์ง„์ž… ๊ฐ€๋Šฅ ํ•จ์ˆ˜โ€™ ๋ผ ํ•œ๋‹ค. ์ฆ‰, Thread-safe ํ•œ ํ•จ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กฑ ์ „์—ญ๋ณ€์ˆ˜, ํ˜น์€ static ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•จ์ˆ˜๋Š” โ€˜์žฌ์ง„์ž… ๋ถˆ๊ฐ€๋Šฅโ€™ ํ•˜๋‹ค. strtok๋Š” ๋Œ€ํ‘œ์ ์ธ ์žฌ์ง„์ž… ๋ถˆ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜์ด๋‹ค. func1() { strtok() } func2() { strtok() } main() { pthread_create(func1); pthread_create(func2); } // -> strtok๋Š” ์žฌ์ง„์ž… ๋ถˆ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ณผ๊ฐ€ ์˜๋„ํ•œ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ค์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. C ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” strtok_r ์ด๋ผ๋Š” ์žฌ์ง„์ž… ๊ฐ€๋Šฅํ•œ ํ•จ์ˆ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค. TLS / TSD TLS๋Š” thread ์˜ ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๊ณต๊ฐ„์œผ๋กœ, ๋กœ๋”(Loader)์— ์˜ํ•ด์„œ ํ• ๋‹น๋œ๋‹ค. ๋ฆฌ๋ˆ…์Šค์—์„œ๋Š” TSD๋ผ ๋ถ€๋ฅธ๋‹ค. int pthread_setspecific(pthread_key_t key, const void *value) : โ€˜keyโ€™ ์— ํ•ด๋‹นํ•˜๋Š” ์˜์—ญ์— โ€˜valueโ€™๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค. value๋กœ๋Š” ๋™์ ํ• ๋‹นํ•œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์˜จ๋‹ค. void* pthread_getspecific(pthread_key_t key) : ๊ธฐ์กด์— set์œผ๋กœ ํ• ๋‹นํ•œ key์— ํ•ด๋‹นํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค. void pthread_key_create(pthread_key_t key, void* (*descturctor)(void*)) ํ• ๋‹นํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•  ํ•จ์ˆ˜ void destructor(void* ptr){free(p);}๋ฅผ ์ •์˜ํ•˜๊ณ , destructor์˜ ํฌ์ธํ„ฐ๋ฅผ key์™€ ๋งคํ•‘์‹œํ‚จ๋‹ค. void main(void) { pthread_key_t key; pthread_key_create(key, void (*destructor)(void*)); } void func1(void) { int *tsd = pthread_get_specific(key) // key์— ํ•ด๋‹นํ•˜๋Š” ์˜์—ญ ๊ฐ€์ ธ์˜ด if (!tsd) // null ๋ฐ›์•˜์„ ์‹œ { tsd = calloc(1, sizeof int); // int ์˜์—ญ์ด ํ•„์š”ํ•ด์„œ ๋™์ ํ• ๋‹น. ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•๋„ ๊ฐ€๋Šฅ pthread_set_specific(key, tsd); // TSD ์˜์—ญ์— ์ €์žฅ } } void destructor(void* ptr) { free(p); } TLS๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ void* tls[] ๋ฐฐ์—ด์„ bitmap ํ˜•ํƒœ๋กœ ์ง€๋‹ˆ๊ณ , pthread_set_specific์„ ํ•  ๊ฒฝ์šฐ tls[idx]์— ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๋ฅผ ๋Œ€์ž…ํ•œ๋‹ค. pthread_set_specific์„ ํ˜ธ์ถœํ•  ๋•Œ ๋งˆ๋‹ค idx๋Š” ์ž๋™์œผ๋กœ ๊ฐฑ์‹ ๋œ๋‹ค. thread๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ ๋ชจ๋“  key์— ๋Œ€ํ•ด ์†Œ๋ฉธ์ž๋กœ ์ •์˜๋œ destructor๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

<span title='2023-07-23 15:05:46 +0900 KST'>July 23, 2023</span>&nbsp;ยท&nbsp;5 min&nbsp;ยท&nbsp;AswinBlue

Process

Process Program vs Process Process : ์‹คํ–‰์ค‘์ธ ํ”„๋กœ๊ทธ๋žจ Program : ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ํŒŒ์ผ Process๋Š” ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€ ์žˆ๋Š” ์ƒํƒœ์˜ ํ”„๋กœ๊ทธ๋žจ์„ ์˜๋ฏธํ•œ๋‹ค. C์–ธ์–ด Program to Process C์–ธ์–ด๋กœ ๊ตฌ์„ฑ๋œ ํ”„๋กœ๊ทธ๋žจ์€ ์ „์ฒ˜๋ฆฌ - ์ปดํŒŒ์ผ - ๋งํ‚น - ๋กœ๋”ฉ์˜ ๊ณผ์ •์„ ๊ฑฐ์นœ๋‹ค. ์ „์ฒ˜๋ฆฌ : # ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ผ์ธ๋“ค์„ ์•Œ๋งž์€ ํ˜•ํƒœ๋กœ ์น˜ํ™˜ํ•œ๋‹ค. ์ปดํŒŒ์ผ : C์–ธ์–ด(high-level language)๋ฅผ ์–ด์…ˆ๋ธ”๋ฆฌ์–ด(๊ธฐ๊ณ„์–ด) ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ๋งํ‚น : ์™ธ๋ถ€์˜ ELF(Executable and Linkable Format) ํŒŒ์ผ๋“ค์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ์—ฐ๊ฒฐํ•œ๋‹ค. ๋กœ๋”ฉ : ์ตœ์ข… ์ƒ์„ฑ๋œ ํŒŒ์ผ์„ ์‹คํ–‰์‹œ์ผœ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ ค ํ”„๋กœ์„ธ์Šค๋กœ ๋งŒ๋“ ๋‹ค. ๋ฆฌ๋ˆ…์Šค์—์„œ๋Š” execv() ํ•จ์ˆ˜์— ์˜ํ•ด ํ”„๋กœ์„ธ์Šคํ™” ๋œ๋‹ค. ํ”„๋กœ์„ธ์Šค fork fork() ํ•จ์ˆ˜๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณต์‚ฌํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค. unistd.h ํ—ค๋”์— ์„ ์–ธ๋˜์–ด ์žˆ๋‹ค. ๋ณต์‚ฌ๋‹นํ•œ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค, ๋ณต์‚ฌํ•ด์„œ ์ƒ์„ฑ๋œ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ผ ํ•œ๋‹ค. ๋ณต์‚ฌ๋œ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋„ fork ์‹คํ–‰ ์ดํ›„๋ถ€ํ„ฐ ์ฝ”๋“œ๊ฐ€ ์ง„ํ–‰๋œ๋‹ค. fork ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์€ pid_t ํƒ€์ž…์ด๋‹ค. ๋ฐ˜ํ™˜๊ฐ’์ด -1์ด๋ผ๋ฉด ์‹คํŒจ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๊ฒฐ๊ณผ๊ฐ€ 0์ด๋ผ๋ฉด ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๋Š” ์ž์‹ ํ”„๋กœ์„ธ์Šค์ž„์„ ์˜๋ฏธํ•œ๋‹ค. 0์ด ์•„๋‹ˆ๋‹Œ ๊ฐ’์ด๋ผ๋ฉด ํ˜„์žฌ ํ”„๋กœ์„ธ์Šค๋Š” ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค์ด๋‹ค. ๋ฐ˜ํ™˜๊ฐ’์€ ์ž์‹ํ”„๋กœ์„ธ์Šค์˜ process id๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, ๋ฆฌ๋ˆ…์Šค ๋ช…๋ น์–ด ps -ef ๋กœ pid๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. Race Condition : ์ผ๋‹จ fork๊ฐ€ ๋˜์–ด ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ถ€๋ชจ ์ž์‹์œผ๋กœ ๋‚˜๋‰˜๋ฉด, ํ”„๋กœ์„ธ์Šค์˜ ์‹คํ–‰์€ ๋ณ‘๋ ฌ์ ์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋ฉฐ, ๊ฐ™์€ ์ฝ”๋“œ๋ผ๋„ ์–ด๋А ๊ฒƒ์ด ๋จผ์ € ๋™์ž‘ํ• ์ง€ ์•Œ ์ˆ˜ ์—†๋‹ค. wait fork() ๋กœ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑํ•œ ํ›„ ์ž์‹ ํ”„๋กœ์„ธ์Šค๊ฐ€ exit()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ข…๋ฃŒ๋  ๋•Œ, ๋ถ€๋ชจ process๋Š” ์ž์‹ process์˜ ์ข…๋ฃŒ ๊ฒฐ๊ณผ๋ฅผ wait() ์œผ๋กœ ๋ฐ›์„์ˆ˜ ์žˆ๋‹ค. wait(statloc *status) : ์ž์‹ process์—์„œ ํ˜ธ์ถœ๋œ exit() ํ•จ์ˆ˜ ์•ˆ์— ๋“ค์–ด๊ฐ„ ์ธ์ž๊ฐ’์„ status(์ธ์ž๋Š” 4byte int์ง€๋งŒ, ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„์€ 2byte) ์— ๋‹ด์•„๋‚ธ๋‹ค. status ๊ฐ’์€ ์ƒ์œ„ 1byte์™€ ํ•˜์œ„ 1byte๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค. ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๊ฐ€ ๋œ๊ฒฝ์šฐ๋Š” exit() ํ•จ์ˆ˜์— ์˜ํ•œ ์ข…๋ฃŒ๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, status์˜ ์ƒ์œ„ 1byte์— exit์˜ ์ธ์ž๊ฐ’์„ ๋‹ด์•„๋‚ธ๋‹ค. ๋น„์ •์ƒ ์ข…๋ฃŒ๋Š” signal์— ์˜ํ•œ ์ข…๋ฃŒ๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ, signal ๋ฒˆํ˜ธ ๊ฐ’์„ status์˜ ํ•˜์œ„ 1byte์— ๋‹ด์•„๋‚ธ๋‹ค. 0~7๋ฒˆ bit : ์ž์‹ process ์ •์ƒ์ข…๋ฃŒ์‹œ ์ข…๋ฃŒ status 8๋ฒˆ bit : core dump ์—ฌ๋ถ€ 9~15๋ฒˆ bit : ์‹œ๊ทธ๋„ ๋ฒˆํ˜ธ status๊ฐ’์„ ์ธ์ž๋กœ ๋ฐ›์•„ ์ข…๋ฃŒ ์‚ฌ์œ ๋ฅผ ํšŒ์‹ ํ•˜๋Š” ๋งคํฌ๋กœ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‰ฝ๊ฒŒ ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค. WIFEXITED, WEXITEDSTATUS, WIFSIGNALED โ€ฆ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณต์‚ฌํ•ด ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑํ•ด๋„ code ์˜์—ญ์€ ๊ณต์œ ๋œ๋‹ค. code ์˜์—ญ์€ read only memory ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž์‹ ํ”„๋กœ์„ธ์Šค๋Š” ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค์˜ ram ์˜์—ญ ๊ฐ’๋„๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ ํ•ด ์˜จ๋‹ค. ํ•˜์ง€๋งŒ, ์ž์‹ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ƒˆ์„ฑ๋  ๋‹น์‹œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ฐ”๋กœ ๋ณต์‚ฌ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฉ”๋ชจ๋ฆฌ์— ๊ฐ’์„ ์ž‘์„ฑํ•˜๋Š” ์‹œ์ ์— ๋ณต์‚ฌ๊ฐ€ ๋œ๋‹ค. ์ฆ‰, ๋ถ€๋ชจ๋‚˜ ์ž์‹ ํ”„๋กœ์„ธ์Šค์—์„œ ๊ฐ’์„ ๋ฎ์–ด์“ฐ๊ฑฐ๋‚˜ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š์€ ๋ณ€์ˆ˜์— ๋Œ€ํ•ด์„œ๋Š” ๊ฐ™์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ๋Š” reference count๋ฅผ ๋“ค๊ณ  ์žˆ์–ด ๋ช‡๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค์—์„œ ํ•ด๋‹น ์˜์—ญ์„ ์ฐธ์กฐํ•˜๋Š”์ง€ ์ฒดํฌํ•œ๋‹ค. ํ”„๋กœ์„ธ์Šค ์ƒ๋ช… ์ฃผ๊ธฐ (Life Cycle) ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๋Š” ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์žˆ๊ณ , ๊ฐ€์žฅ ์ตœ์ดˆ๋กœ ์‹คํ–‰๋œ ํ”„๋กœ์„ธ์Šค๋ฅผ init ํ”„๋กœ์„ธ์Šค๋ผ ํ•˜๋ฉฐ, init ํ”„๋กœ์„ธ์Šค์˜ pid๋Š” 1์ด๋‹ค. ...

<span title='2023-07-18 20:15:29 +0900 KST'>July 18, 2023</span>&nbsp;ยท&nbsp;8 min&nbsp;ยท&nbsp;AswinBlue

System_programming

System Programming ํ”„๋กœ๊ทธ๋žจ์ด ๋™์ž‘ํ•˜๋Š” ๊ตฌ์กฐ๋Š” ํฌ๊ฒŒ application, kernel, HW ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. _____________ | Library | ยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏ Application level ------------------------------ _____________ |System call| ยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏ Kernel level ------------------------------ _____________ | Hardware | ยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏยฏ H/W level ------------------------------ application level์—์„œ๋Š” library๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์ด ์ฝ”๋“œ๋“ค์€ library buffer๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. (open(), read(), write(), close() โ€ฆ) ์‹œ์Šคํ…œ์—์„œ ์ œ๊ณตํ•˜๋Š” ์ตœ์ ์˜ buffer ๋‹จ์œ„๋กœ disk์—์„œ ๊ฐ’์„ ์ฝ์–ด์˜ค๊ณ , library buffer์— ๋‹ด์•„๋‘๋ฉด ์ž‘์€๋‹จ์œ„๋กœ ์ฝ์–ด์˜ฌ ๋•Œ ํšจ์œจ์ ์ด๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด, ํ•œ ์ค„์”ฉ ํŒŒ์ผ์„ ์ฝ์–ด์•ผ ํ•œ๋‹ค๋ฉด, 1byte์”ฉ ํŒŒ์ผ์—์„œ โ€˜\nโ€™์„ ๊ฐ์ง€ํ•  ๋•Œ ๊นŒ์ง€ ์ฝ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, BUF_SIZ๋งŒํผ ํŒŒ์ผ์—์„œ ์ฝ์–ด์„œ library buffer์— ๋‹ด์•„๋‘๊ณ  library buffer๋ฅผ 1byte์”ฉ ์ฝ์œผ๋ฉฐ โ€˜\nโ€™๋ฅผ ์ฐพ๋Š” ๊ฒƒ์ด ์‹คํ–‰ ์†๋„๋Š” ๋” ๋น ๋ฅด๋‹ค. (IO์ ‘๊ทผ์€ ์ ์„์ˆ˜๋ก ํšจ์œจ์ ) Kernel level์—์„œ๋Š” System call์„ ์‚ฌ์šฉํ•˜๋ฉฐ system buffer๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. application level ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ๋ณดํ†ต library buffer๋ฅผ 1์ฐจ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ , ๋‚ด๋ถ€์ ์œผ๋กœ system call์„ ์ˆ˜ํ–‰ํ•ด system buffer๋ฅผ 2์ฐจ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค. printf๋Š” c library ํ•จ์ˆ˜์ด๋ฉฐ, โ€˜\nโ€™์„ ๋งŒ๋‚˜์•ผ ํ™”๋ฉด์ƒ์— ์ถœ๋ ฅ์„ ํ•œ๋‹ค. โ€˜\nโ€™์ด ์ž…๋ ฅ๋˜๊ธฐ ์ „ ๊นŒ์ง€ ๋ฌธ์ž์—ด๋“ค์€ library buffer์— ๊ธฐ๋ก๋œ๋‹ค. fprintf๋Š” โ€˜\nโ€™๊ณผ ์ƒ๊ด€์—†์ด ๋ฌธ์ž์—ด์„ ์ถœ๋ ฅํ•œ๋‹ค. ์ฆ‰ library buffer๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค. ํŒŒ์ผ ์ž…์ถœ๋ ฅ fgetc C์—์„œ ํŒŒ์ผ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” fopen ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. fopen์€ ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ์ฝ”๋“œ ๋‚ด์—์„œ ํŒŒ์ผ ํฌ์ธํ„ฐ๋กœ ํ•ด๋‹น ํŒŒ์ผ์— ์ ‘๊ทผ์ด๊ฐ€๋Šฅํ•˜๋‹ค. fgetc(FPTR) ํ•จ์ˆ˜๋Š” fopen์œผ๋กœ ์—ฐ ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ์ฐธ์กฐํ•ด์„œ char ํ•˜๋‚˜๋ฅผ ์ฝ๊ณ  ๋ฐ˜ํ™˜ํ•œ๋‹ค. fgetc ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ int ํ˜•ํƒœ์ด๋‹ค. text file์„ ์ฝ์„ ๋•, 0xFF๊ฐ’์ด ๋‚ด์šฉ์— ์˜ฌ ์ˆ˜ ์—†์ง€๋งŒ, binary file์„ ์ฝ์„ ๋• ์ค‘๊ฐ„์— 0xFF ๊ฐ’์ด ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. char ํ˜•ํƒœ๋กœ 0xFF๋ฅผ ์ฝ์œผ๋ฉด -1๊ฐ’์— ํ•ด๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์—, EOF์™€ ๊ตฌ๋ถ„์ด ๋ถˆ๊ฐ€๋Šฅํ•˜์—ฌ char ๋Œ€์‹  int๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋˜์–ด์žˆ๋‹ค. ํŒŒ์ผ ๊ตฌ์กฐ์ฒด fopen์€ ํŒŒ์ผ ๊ตฌ์กฐ์ฒด์˜ ์ฃผ์†Œ(ํฌ์ธํ„ฐ)๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํŒŒ์ผ ๊ตฌ์กฐ์ฒด๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ๋‹ค. _flags: _IO_read_ptr : ๋‹ค์Œ ๋ช…๋ น์‹œ ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ์“ธ ์œ„์น˜ _IO_read_end: kernel์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ ์ €์žฅํ•  ๋ฒ„ํผ์˜ ๋ ์œ„์น˜. _IO_read_base: kernel์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ ์ €์žฅํ•  ๋ฒ„ํผ์˜ ์‹œ์ž‘ ์œ„์น˜. ํŒŒ์ผ์— ๋Œ€ํ•œ ์ฝ๊ธฐ ๋ช…๋ น(fgetc/fgets๋“ฑ) ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, kernel์€ 4096byte(BUF_SIZE) ๋งŒํผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฏธ๋ฆฌ ์ฝ์–ด์„œ ์ด๊ณณ์— ์ฑ„์›Œ๋‘”๋‹ค. _fileno: ํŒŒ์ผ์˜ offset, kernel์—์„œ ํ•ด๋‹น ํŒŒ์ผ์— ์ •ํ•ด์ค€ index(kernel ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.) fopen ์‹œ์— ํŒŒ์ผ ๊ตฌ์กฐ์ฒด๊ฐ€ ์ƒ์„ฑ ๋ฐ ์ดˆ๊ธฐํ™” ๋˜์ง€๋งŒ, IO_read* ์ธ์ž๋“ค์€ ํŒŒ์ผ ์ ‘๊ทผ์ด ์ด๋ฃจ์–ด์ง๊ณผ ๋™์‹œ์— ๊ฐ’์ด ์ ์šฉ๋œ๋‹ค. EOF ํŒŒ์ผ์„ ๋๊นŒ์ง€ ์ฝ์—ˆ๋‹ค๊ณ  ํŒ๋‹จํ•˜๋Š” ๊ฒƒ์€, EOF ๋ฌธ์ž(-1) ์œผ๋กœ ํŒ๋‹จํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œํŒŒ์ผ์„ ์ฝ์–ด๋ณด๋ฉด ๋งˆ์ง€๋ง‰์— -1๊ฐ’์ด ์‹ค์ œ๋กœ ๋“ค์–ด์žˆ์ง€๋Š” ์•Š๋‹ค. EOF ๊ฐ’์€ file I/O ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด๊ฐ’์ผ ๋ฟ ์‹ค์ œ ํŒŒ์ผ์— ๊ธฐ์ž…๋œ ๊ฐ’์ด ์•„๋‹ˆ๋‹ค. file I/O ํ•จ์ˆ˜๋Š” i-node์— ๊ธฐ๋ก๋œ ํŒŒ์ผ์˜ ํฌ๊ธฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํŒŒ์ผ ๋์„ ํŒ๋‹จํ•œ๋‹ค. ASKII ์ฝ”๋“œ ์ค‘ ์ฃผ์š” ๋ฌธ์ž์˜ ๊ฐ’ ์ฐธ์กฐ a: 97 A: 68 0: 48 \n: 10 \r: 13 (๊ณต๋ฐฑ): 32 \t: 9 \0: 0 fguts(BUFF, SIZE, FPTR) ํ•จ์ˆ˜๋Š” fopen์œผ๋กœ ์—ฐ ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ์ฐธ์กฐํ•ด์„œ line ํ•˜๋‚˜๋ฅผ ์ฝ์–ด์˜จ๋‹ค. fputs(BUFF, FPTR) ํ•จ์ˆ˜๋Š” fopen์œผ๋กœ ์—ฐ ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ์ฐธ์กฐํ•ด์„œ line ํ•˜๋‚˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๋ฆฌ๋ˆ…์Šค์—์„œ ํ‘œ์ค€ ์ž…๋ ฅ/์ถœ๋ ฅ/์—๋Ÿฌ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํŒŒ์ผ ํฌ์ธํ„ฐ๋ฅผ ์—ด์–ด๋‘”๋‹ค. ๊ฐ๊ฐ ์•„๋ž˜ ๋ฌธ์ž์—ด ํ˜น์€ ๋ฒˆํ˜ธ๋กœ ์ฐธ์กฐ ๊ฐ€๋Šฅํ•˜๋‹ค. stdin : ํ‘œ์ค€ ์ž…๋ ฅ stdout : ํ‘œ์ค€ ์ถœ๋ ฅ stderr: ํ‘œ์ค€ ์—๋Ÿฌ -> ํŒŒ์ผ ํฌ์ธํ„ฐ ๋Œ€์‹  stdout ์„ ์ž…๋ ฅํ•˜๋ฉด ํ‘œ์ค€ ์ถœ๋ ฅ์œผ๋กœ ๋ฌธ์ž์—ด์ด ์ถœ๋ ฅ๋œ๋‹ค. (ex: fputc(BUF, stdout)) ...

<span title='2023-07-15 08:35:21 +0900 KST'>July 15, 2023</span>&nbsp;ยท&nbsp;10 min&nbsp;ยท&nbsp;AswinBlue

Shell Programming

Shell Programming ๋ฆฌ๋ˆ…์Šค ์‰˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์— ๋Œ€ํ•ด ๊ธฐ์ˆ ํ•œ๋‹ค. ์‰˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ bash, sh ๋“ฑ์˜ ๋ช…๋ น์–ด๋ฅผ ํ™œ์šฉํ•œ ๋กœ์ง์„ ์นญํ•˜๋ฉฐ, ๋ฆฌ๋ˆ…์Šค ํ™˜๊ฒฝ์—์„œ text ํŒŒ์ผ ์•ˆ์— ๋ช…๋ น์–ด๋ฅผ ์ž‘์„ฑํ•ด ๋†“๊ณ , ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ๋ช…๋ น์–ด๊ฐ€ ๋“  ํŒŒ์ผ์˜ ํ™•์žฅ์ž๋Š” ๋ณดํ†ต .sh ๋กœ ์„ธํŒ…ํ•œ๋‹ค. (์œˆ๋„์šฐ OS์˜ .batch ์™€ ์œ ์‚ฌ) .sh ํŒŒ์ผ ์ž‘์„ฑ ์ƒˆ๋กœ ์ƒ์„ฑ๋œ text ํŒŒ์ผ์€ ํ™•์žฅ์ž๊ฐ€ .sh ๋ผ๋„ ์‹คํ–‰ ๊ถŒํ•œ์ด ์—†๊ธฐ ๋–„๋ฌธ์— chmod ๋ช…๋ น์–ด๋กœ ๊ถŒํ•œ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค. ex) chmod a+x <ํŒŒ์ผ์ด๋ฆ„> ๋ช…๋ น์œผ๋กœ ๋ชจ๋“  ์‚ฌ์šฉ์ž์— ๋Œ€ํ•ด ์‹คํ–‰ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค. .sh ํŒŒ์ผ ์•ˆ์—๋Š” shell ๋ช…๋ น์–ด๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ ์™ธ ์ถ”๊ฐ€์ ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ตฌ๋ฌธ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. ...

<span title='2023-07-13 18:29:44 +0900 KST'>July 13, 2023</span>&nbsp;ยท&nbsp;1 min&nbsp;ยท&nbsp;AswinBlue