concurrent 한 task를 하기 위한 방법(monitoring file descriprtors)
1. 프로세스를 여러개만들자.
2. select, poll함수를 사용하자.(blocking함수) 다중스레드를 사용하지 않고 싱글스레드 기반에서 이 두 함수를 써서 서버를 구축할 수 있음. 그러나 함수하나가 실행중일 때 다른 작업을 하지 못한다는 제한적인 부분이 있음
3. nonblocking I/O with polling으로 모니터링을 할 수 있다. 얼마나 자주 모니터링을 해야 하는지 타이머에 관한 부분을 모니터링해야 한다는 단점이 있다.
4. POSIX asynchronous I/O를 사용하자. 백그라운드로 요청한 사실을 수동으로 확인하려면 timing문제가 있고 시그널로 확인하려면 시그널핸들러를 사용해야 하는데 시그널을 쓸 때 주의사항이 있었다.
5. 결론은 스레드를 여러 개 만들자.
다중스레드는 왜 사용하냐?
여러 독립적인 스레드를 동시에 실행해서 전체 task 퍼포먼스를 향상하기 위해서
다중스레드를 사용하면 asynchronous 한 이벤트를 효율적으로 처리할 수 있다. 또한 paralled performance를 얻을 수 있다.
스레드를 너무 많이 만들면 퍼포먼스가 떨어질 수 있음
스레드라는 개념은 무엇이냐?
각각의 스레드는 실행흐름이라고 나타낸다.
스레드는 다중 프로세스와 닮았는데, 차이점은 스레드는 공유메모리를 보유하고 있어서 os의 도움 없이 커뮤니케이션이 가능하다.
스레드들은 사람눈에는 동시(simultaneously)에 실행되는 거처럼 보이는데 실제로는 concurrent 하게 실행된다.
multitasking
싱글 프로세스에서도 가능하고 멀티 프로세스에서도 가능하다.
싱글 프로세스에서는 time-division multiplexing(여러 스레드를 번갈아가면서 실행하는 것)을 통해서 concurrent 하게 작동한다.
멀티프로세서 or 멀티코어 시스템인 경우에 실제로 프로세스들이 동시(simultaneously)에 실행이 된다.
Psocesses vs threads
프로세스들은 독립적이다. 왜냐하면 프로세스는 서로 다른 메모리공간을 가지고 공유메모리도 없기 때문이다.
스레드는 각자 사용하는 메모리도 갖고 공유메모리도 갖고 있다.
프로세스는 스레드와 비교했을 때 관리해야 할 상태 정보가 많다. ex) cotext switch
프로세스들은 각자 분리된 분리된 주소 공간을 갖고 있다.
프로세들 까리 커뮤니케이션을 하러면 inter-process communicaton 메커니즘이 필요하다. 즉, OS의 도움이 필요하다.
스레드는 별도의 도움이 필요가 없음, 공유메모리를 사용하면 되기 때문에
다중스레드가 좋은 것만은 아니다.
스레드 간의 동기화 문제를 해결해야 한다.
프로세스는 kernel이 scheduling 할 수 있는 가장 heavies한 유닛이다.
스레드는 kernel이 scheduling할 수 있는 가장 lightest 한 유닛이다.
프로세스는 preemptively(선점적) multitasked이다. (언제는 실행 중이다가 쫓겨날 수 있음)
스레드가 프로세스보다 오버헤드가 적다.
각각의 프로세스 하나당 스레드는 하나씩 기본으로 생김
OS가 preemptive 한 스케줄링 알고리즘을 사용한다면 스레드도 동일하게 사용가능하다.
스레드는 리소스를 소유하지 않는다.(단, stack, 레지스터, 프로그램카운터, thread-local storage는 예외)
스레드는 커널스레드와 유저 스레드로 나눌 수 있다. 커널 스레드는 커널이 관리할 수 있는 스레드이고 유저 스레드는 커널이 스레드의 존재를 모르고 유저레벨의 라이브러리에 의해서 관리되는 스레드이다. 요즘엔 딱히 구분 안 함
User space : 애플리케이션이 사용하는 메모리 공간
kernel space : 커널이 사용하는 메모리 공간
커널이 실행할 때 사용하는 공간과 커널이 실행할때 필요한 메모리 공간을 커널 스페이스로 분리할 수 있다. 대부분의 커널 메모리는 절대로 디스크에서 swapped out 되지 않는다.(퍼포먼스가 떨어질 수 있기 때문에)
그래서 swapp in out은 userp space에서 일어난다.
왜 다중 프로세스를 안 쓰고 Pthread를 쓸까?
스레드를 여러 개 만드는 것이 프로세스를 만드는 것보다 오버헤드가 적어서 시간이 더 빨리 걸리기 때문
POSIX thread 함수들
pthread_cancel : 다른 스레드들을 종료시키는 함수
pthread_create : 스레드를 만든다
pthread_detach : 아래에 자세히 설명
pthread_equal : 스레드의 ID가 같은지 비교하는 함수
pthread_exit : 프로세스하나를 종료
pthread_kill : 스레드에게 시그널을 보내는 함수
pthread_join : 스레드를 기다리는 함수
pthrea_self : 자신의 프로세스 ID를 얻어오는 함수
성공 시 0 에러 시 -1
EINTR을 반환하지 않아서 인터럽트가 발생돼도 재시작할 필요가 없다.
위에는 malloc함수를 통해서 동적메모리로 할당한 부분은 메인 스레드에서 참조를 한 다음에 free를 해줘야 불필요한 메모리낭비를 막을 수 있었다. 그래서 정적변수인 static으로 선언해서 결괏값을 넘겨주는 방법이 있었는데 이방법은 하나의 경스레드에서만 작동을 했다. 왜냐하면 파일복사 스레드가 여러개 생성될 경우에 모든 결과값이 하나의 static변수에 할당되기 때문이다.
그래서 카피한 결과값을 array에 담는 방법이 나오게 되었다. 이런 식으로 한다면 별도로 리턴을 할 필요 없이 array공간을 액세스 하면 된다. 즉, 메인 스레드가 array의 포인터를 넘겨줄 때 array에다가 리턴값을 받을 수 있는 공간을 하나 더 추가해서 넘겨주자. 그러면 array파라미터의 크기는 3이고 세 번째 파라미터에 복사한 값을 카피한다. 그래서 어레이에서 직접 받을 수 있고 join함수의 두 번째 파라미터에서도 받을 수 있다.
Thread safety : 하나의 리소스에 여러 스레드가 액세스 할 때 충돌이 발생하지 않는 함수
asy signal safe 한 함수 : 시그널 핸들러 안에서 안전하게 호출할 수 있는 함수, 메인 프로그램과 시그널 핸들러 부분에서 동시에 호출을 할 때 충돌문제가 발생하지 않는 함수라고 했었다.
이 두 개의 함수 중에서 어떤 것이 만들기 어려울까? asy는 다중 프로세스가 아니더라도 발생할 수 있다. 그렇기 때문에 만들기 쉬운 것은 thread safety함수이다.
'Computer Science > 시스템 프로그래밍' 카테고리의 다른 글
[시스템 프로그래밍] Chapter 14 (0) | 2024.06.11 |
---|---|
[시스템 프로그래밍] Chapter 13 (0) | 2024.06.10 |
[시스템 프로그래밍] Chapter 9 (0) | 2024.06.08 |
[시스템 프로그래밍] Chapter 8 (0) | 2024.05.09 |
[시스템 프로그래밍] Chapter 6 (0) | 2024.05.09 |