학부 수업 정리/시스템프로그래밍 (21-2) (15) 썸네일형 리스트형 [시스템] 7. Threads 1. Threads (스레드) 스레드는 프로세스의 실행단위를 의미한다. 각 스레드는 context of the process 에서 실행되며, 같은 코드와 전역 변수를 공유한다. 즉, 프로세스끼리는 자원 공유가 힘들었던 반면 스레드는 자원을 공유하기가 매우 편리하다. (동일 프로세스 내에서 스레드끼리 같은 메모리의 스택 영역에서 실행된다.) fork(): 자식 프로세스 생성 exec(): 새로운 프로세스로 대체 pthread_create(): 새로운 스레드 생성 2. pthread_create(): 스레드 생성 $\verb|int pthread_create(pthread_t *thread,|$ $\verb|const pthread_attr_t *attr, void* (*start) (void *), voi.. [시스템] 6. IPC (Inter Process Communication) 1. IPC 소개 Signal은 프로세스 사이에 메시지를 보내는 아주 간단한 방법이다. 하지만 전송할 수 있는 정보는 단순히 시그널 숫자 뿐이므로 프로세스들끼리 더 많은 메시지들을 전송하기 위해서는 IPC라는 새로운 방법이 필요하다. IPC의 종류에는 Pipe, Message Queue, Shared Memory, Shmaphore 가 있다. (수업에서는 Pipe와 Message Queue를 위주로 다루었다.) 2. Pipe 단방향 데이터 채널 FIFO - 큐처럼 작동 Stream (바이트) 단위로 전송하기 때문에 메시지의 경계가 존재하진 않는다. System Call: $\verb|pipe()|$ - 파이프 생성 / $\verb|read(), write()|$ 커맨드 창에서 파이프의 사용: $\text.. [시스템] 5. Race Condition & Signal Blocking 1. Race Condition - Simple 예제 시그널핸들러와 이 시그널을 호출하는 main() 함수에 둘 다 $\verb|*i = *i + value;|$ 코드가 있다고 생각하자. 이 코드를 어셈블리 코드로 나타내면 아래와 같다. (ecx, edx는 각 레지스터 이름에 해당하는 변수 이름을 임의로 지정하였다.) my_sighanler: ecx = *i; // movq (%rax), %ecx #1 ecx = ecx + value; // addl %eax, %ecx #2 *i = ecx; // movq %ecx, (%rax) #3 main: edx = *i; // movq (%rax), %edx #4 edx = edx + value; // addl %eax, %edx #5 *i = edx; // mo.. [시스템] 4. 어셈블리 기초 1. 메모리 주소의 표현 모드 $$\verb|D(Rb, Ri, S) -> Mem[Reg[Rb] + S*Reg[Ri] + D]|$$ 왼쪽의 표현식은 오른쪽 공식에 의해 생성되는 숫자로 나타낸다. 이 숫자가 메모리 주소가 된다. $\verb|Rb|$ : Base Register 주소 (16개의 정수 레지스터) $\verb|Ri|$ : Index Register 주소 (\%rsp 제외한 모든 레지스터) $\verb|S|$ : Scale - 1, 2, 4, 8 (Short, int, long 타입 보정용. 디폴트는 1) $\verb|D|$ : Constant Displacement - 1, 2, 4 bytes Expression Address Computation Address $\texttt{0x8(%rdx).. [시스템] 3. Signal 프로그래밍 1. Signal Signal(시그널)은 간단한 메시지를 특정 프로세스에게 보내는 것을 의미한다. 시그널을 보내는 주체는 kernel이고, 프로세스가 다른 프로세스에게 보낼 때도 kernel을 통하게 된다. 시그널은 정수 ID 값으로 구별한다. 예를 들어, 시그널 중 $\verb|SIGKILL|$ 의 ID는 9번으로, 프로그램을 강제 종료시키는 역할을 한다. 커널이 시그널을 보내면 목표 프로세스 안에 자신의 state 정보를 저장하는 자료구조에 시그널이 도착했다는 표시를 남긴다. 나중에 CPU를 할당받았을 때 자신한테 도착한 시그널을 보고 해당 핸들러들을 호출하게 된다. 커널이 시그널을 보내게 되는 계기는 다음과 같다. 커널이 스스로 판단하여 시그널을 보내는 경우: ex) 프로그램 실행 중 0으로 나누는.. [시스템] 2. 멀티 프로세스 프로그래밍 1. Zombies Zombie는 프로세스가 종료되었음에도 불구하고 여전히 시스템 자원을 소비하고 있는 것을 말한다. 좀비가 많아지면 pid를 다 써서 새로운 프로세스를 못 만들게 되는 상황이 생길 수 있다. 좀비를 제거하는 행위는 Reaping 이라 하며, 종료된 자식의 부모가 처리한다. 만약 부모가 자식을 Reaping 하지 않고 종료될 경우, 모든 프로세스의 조상 프로세스인 init 프로세스가 자식을 Reaping 한다. 서버 프로그램처럼 부모 프로세스가 오랫동안 종료되지 않아야 한다면 init 프로세스가 Reaping 하지 않으므로, 부모 내에서 자식 프로세스가 좀비가 되지 않도록 꼭 처리해야 한다. 좀비 프로세스 : 자식 프로세스가 종료되었지만, 부모 프로세스가 아직 그 종료를 확인하지 않는 프.. [시스템] 1. Processes - 생성과 삭제 1. Context Switch 프로세스들은 같은 시스템 내에서 동시에 실행될 수 있는데, 이는 Context Switch에 의해서 일어난다. 각 프로세스들은 자신만의 Control flow 가 존재하는데 Context Switch 가 발생하면 저장하고 다른 프로세스를 실행한 뒤에, 다시 원래 저장된 정보를 환원하여 실행한다. 2. fork: Creating new processes $\verb|pid_t fork(void)|$ fork는 부모 프로세스와 똑같은 자식 프로세스를 생성한다. 자식 프로세스는 0을 리턴하고, 부모 프로세스는 자식의 pid를 리턴한다. 두 프로세스로 나뉘어 실행되지만, 어느 것이 먼저 실행되는지는 모른다. getpid(): 현재 진행되는 자신의 프로세스 아이디를 리턴한다. 부모.. 이전 1 2 다음