세마포어는 18-4에서 다룬 뮤텍스와 유사합니다. 여기서는 0과 1만을 사용하는 바이너리 세마포어라는 것을 대상으로 쓰레드의 실행순서 컨트롤 중심의 동기화를 다룹니다. #include int sem_init(sem_t *sem, int pshared, unsigned int value); int sem_destroy(sem_t *sem); //success:0 fail:0 이외의 값 위 두 함수는 세마포어의 생성 및 소멸에 관한 함수입니다. sem에는 세마포어의 참조 값 저장을 위한 변수의 주소 값 전달(소멸 시에는 소멸시키려는 세마포어의 참조 값을 저장하고 있는 변수의 주소 값 전달), pshared에는 0 전달 시 하나의 프로세스 내에서 접근 가능, 0 이외의 값 전달 시 둘 이상의 프로세스에 의해 ..
C
뮤텍스란 Nutual Exclusion의 줄임말로, 쓰레드의 동시접근을 허용하지 않는다는 의미가 있습니다. 특정 영역을 접근할 때 자물쇠를 채우고, 나갈 때 자물쇠를 푸는 방식으로 활용됩니다. #include int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); int pthread_mutex_destroy(pthread_mutex_t *mutex); //success:0 fail:0 이외의 값 위 두 함수는 각각 뮤텍스 자물쇠 시스템 생성 및 소멸 함수입니다. mutex 인자에는 뮤텍스의 참조 값 저장을 위한 변수의 주소 값을 전달하고, 뮤텍스 소멸시에는 소멸하고자 하는 뮤텍스의 참조 값을 저장하고 있는 변수의 ..
둘 이상의 쓰레드를 생성할 때, 둘 이상의 쓰레드가 동시에 호출하면 문제를 일으키는 문장의 영역을 임계영역이라 합니다. 따라서 함수는 임계영역과 관련해서 두 종류로 나뉘어집니다. 쓰레드에 안전한 함수(Thread-safe Function) 쓰레드에 불안전한 함수(Thread-unsafe Function) 쓰레드에 안전한 함수에도 임계영역이 있을 수 있는데, 둘 이상의 쓰레드가 동시에 접근해도 문제를 일으키지 않도록 적절한 조치가 이뤄졌기에 안전한 것입니다. 다행히 기본적으로 제공되는 대부분의 표준함수는 쓰레드에 안전하고, 쓰레드에 불안전한 함수는 안전한 형태로 재 구현된 함수가 존재하며 쓰레드와 안전한 함수와 불안전한 함수의 구분을 직접할 필요는 없습니다. 헤더파일 선언 이전에 매크로 _REENTRANT..
쓰레드는 별도의 실행흐름을 가지기에 쓰레드만의 main 함수가 필요합니다. 그리고 이 함수를 시작으로 별도의 실행흐름을 형성해 줄 것을 운영체제에게 요청해야 합니다. #include int pthread_create( pthread_t * restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg ); //success: 0 fail: 0을 제외한 값 thread: 생성할 쓰레드의 ID 저장을 위한 변수의 주소 값 attr: 쓰레드에 부여할 특성 정보의 전달을 위한 매개변수로, 기본적인 쓰레드 생성 시 NULL 전달 start_routine: 쓰레드의 main 함수 포인터 arg..
https://pupuduck.tistory.com/63에서는 멀티프로세스 기반의 서버구현에 대해 다뤘는데, 프로세스의 생성은 select나 epoll에 비해 확실히 구분되는 장점이 있지만 큰 단점들이 있었습니다. 프로세스 생성 자체가 부담스럽다. 두 프로세스 사이에서 데이터 교환을 위해선 별도의 IPC 기법을 거쳐야 한다 컨텍스트 스위칭이 초당 수십번에서 수천번까지 일어난다. 여기서 컨텍스트 스위칭이란 A프로세스와 B프로세스가 있고 메인 메모리에 A프로세스가 있을 때, B프로세스를 실행하기 위해 A프로세스 관련 데이터를 메인 메모리에서 하드디스크로 이동시키고 B프로세스를 메인 메모리에 이동시키는 것입니다. 이 과정이 초당 수십번에서 수천번 일어나는 것은 큰 부담이 아닐 수 없습니다. 이 여러 단점을 최..
레벨 트리거 방식은 입력버퍼에 데이터가 남아있는 동안 계속 이벤트가 등록됩니다. 엣지 트리거 방식은 입력버퍼로 데이터가 수신된 상황에서 딱 한 번만 이벤트가 등록됩니다. https://pupuduck.tistory.com/88에 따르면 epoll_event 구조체의 event 변수에 EPOLLET를 지정함으로써 엣지트리거로 변경시킬 수 있습니다. ex) event.events=EPOLLIN|EPOLLET; 엣지 트리거 기반의 서버 구현을 위해선 변수 errno를 이용한 오류 원인 파악과 Non-blocking IO를 위해 소켓의 특성을 변경하는 방법을 알아야합니다. 일반적으로 소켓관련 함수는 오류가 발생했을 때 -1을 반환하는데, 이로써 오류의 원인을 알 수는 없습니다. 헤더파일 errno.h를 incl..
https://pupuduck.tistory.com/78에서 select 함수를 통한 IO 멀티플렉싱을 다뤘습니다. select 함수는 대부분의 운영체제에서 작동한다는 큰 강점이 있습니다. 다만 select 함수는 두 가지 큰 문제점이 있는데, 첫 번째로 모든 파일 디스크립터를 대상으로 반복문을 돌려야 한다는 것이고, select 함수를 호출할 때마다 인자로 관찰대상에 대한 정보들을 매번 전달해야 합니다. 프로그램으로서, 운영체제에게 데이터를 매번 전달하는 것은 많은 부담이 따릅니다. 따라서 운영체제에게 관찰대상에 대한 정보를 한 번만 알려주고 관찰대상의 범위나 내용에 변경이 있을 때 변경 사항만 알려줄 필요가 있습니다. 이는 운영체제가 지원을 해줘야 작동이 가능한데, 이 지원하는 방식을 리눅스에서는 e..
https://pupuduck.tistory.com/85에서 다뤘듯 fdopen 함수로 파일 디스크립터를 FILE형 포인터로 변환시킬 수 있습니다. 그리고 https://pupuduck.tistory.com/70에서 입출력 스트림 분리와 분리했을 때의 장점을 다뤘습니다. 위 글에서는 스트림 분리목적으로 입출력 루틴 독립을 통한 편의성을 느리고, 입력에 상관없이 출력이 가능하게 함으로 속도의 향상을 기대할 수 있었는데, 이 글에서는 읽기모드와 쓰기모드를 구분해야 하는 FILE 포인터를 사용하므로 두 모드의 구분을 통한 편의성 증대와 버퍼링 기능의 향상을 기대할 수 있습니다. 분리된 파일 포인터와 파일 디스크립터, 소켓의 관계는 위와 같이 표현됩니다. 그런데 만약, Half-close를 위해서, 예를 들어 ..