1. 그냥 프로세스가 좀비되는 것을 말씀하시는건지
2. 아니면 시스템콜 관련 함수에서 (recvfrom같은...) blocking되는 것을 말씀하시는건지.....
3. 아니면 무한루프(Busy loop)에 빠져있는 상태를 말씀하시는건지...
4. pthread_join으로 인한 block을 말씀하시는건지...
5. mutex에의 dead lock상태로 인한 block을 말씀하시는건지...
예를 들어 get_thread_state(thread_t *t)란 함수가 있어서 이것의 리턴값이 호출하는 순간의 쓰레드 상태를 나타낸다고 하더라도, 부른쪽에서 이 값을 읽어내는 순간에 쓰레드가 여전히 자고 있는지 아니면 깨어났는지는 알 길이 없습니다. 아마도 일종의 이벤트 통지 메커니즘을 쓰레드 상태를 이용해서 구현하려고 하시는 것 같은데, 쓰레드가 블럭된 적이 있는지는 알아낼 수 있지만, 블럭된 중인지 알아내는 방법은 없는 듯 합니다.
그런데, 윈도의 IOCP는 유닉스 select/poll을 구현하기 위해 만든 것이 아닌가요? 그리고 쓰레드가 블럭중일 때 자동으로 다른 쓰레드를 작동시키는 것은 커널 스케줄러가 하는 일 아닌가요. 설명을 좀 부탁드려도 될지...
가장 큰 차이는 I/O Completion을 알리는 것이고, select/poll은 I/O Ready
를 알리는 것입니다. 다른 차이는, IOCP의 Thread 사용 및 관리에 있습니다.
IOCP의 가장 큰 목적은 I/O가 빈번히 일어나는 서버가 여러 클라이언트 세션
을 Thread들로 유지함에 따라 발생하는 불필요한 switching cost를 없애기
위한 것이기 때문에, 우선적으로 I/O event 에 따라 thread switching을
하게 됩니다.
위의 방식을 구현하기 위하여 일반적인 Thread Library를 사용하게 되면
switching이 원하지 않는 때에 발생하기 때문에 IOCP 형태를 구현하기가
어렵게 됩니다.
@ IOCP가 무조건 가장 좋은 I/O 처리 구조는 아닙니다. 어디까지나 I/O
가 빈번히 발생하며 동시 세션이 많은 서버에서 좋을 뿐입니다. 어느 수준
이하로 가면 큰 차이가 없으며, 오히려 I/O가 적게 일어나는 서버에서는
Response Time이 커지는 세션이 발생할 수 있습니다.
@ 이러한 Event 기반의 처리 시스템에 대해서는 논문도 있고, 실제로 리눅스
상에서 구현을 하는 경우도 있습니다.
The epoll event distribution interface is able to behave both as Edge
Triggered ( ET ) and Level Triggered ( LT ). The difference between ET
and LT event distribution mechanism can be described as follows. Sup-
pose that this scenario happens :
1 The file descriptor that represent the read side of a pipe ( RFD
) is added inside the epoll device.
2 Pipe writer writes 2Kb of data on the write side of the pipe.
3 A call to epoll_wait(2) is done that will return RFD as ready
file descriptor.
4 The pipe reader reads 1Kb of data from RFD.
5 A call to epoll_wait(2) is done.
If the RFD file descriptor has been added to the epoll interface using
the EPOLLET flag, the call to epoll_wait(2) done in step 5 will hang
because of the available data still present in the file input buffers.
The reason for this is that Edge Triggered event distribution delivers
events only when the status of a monitored device changes from I/O
space not available ( state 0 ) to I/O space available ( state 1 ). In
the above example, an event on RFD will be generated ( supposing that
the pipe read buffer was empty before ) because of the write done in 2
, and the event is consumed in 3. Since the read operation done in 4
does not consume the whole buffer data ( that is, the condition remains
I/O space available ) a transition 0 -> 1 cannot happen in 5. The
epoll interface, when used with the EPOLLET flag ( Edge Triggered )
should use non-blocking file descriptors to avoid having a blocking
read or write starve the task that is handling multiple file descrip-
tors. The suggested way to use epoll as an Edge Triggered ( EPOLLET )
interface is below, and possible pitfalls to avoid follow.
i with non-blocking file descriptors
ii by going to wait for an event only after read(2) or write(2)
return EAGAIN
On the contrary, when used as a Level Triggered interface, epoll is by
all means a faster poll(2), and can be used wherever the latter is used
since it shares the same semantics.
엣지 트리거와 레벨 트리거는 원래 전자공학 용어인데, 소프트웨어 분야에도 비슷한 개념을 설명할 때 씁니다. 차이점은 옛지 트리거는 상태의 변화를 탐지하는 반면, 레벨 트리거는 상태의 값을 탐지한다는 것입니다. 예를 들면 버퍼의 상태는 비어있든지(값0), 데이터가 들어있든지(값1) 둘중 하나입니다. 이때 시스템에게 "버퍼에 데이터가 들어 왔느냐"(버퍼 상태가 0에서 1로 변했느냐)고 물어보면 엣지 트리거이고, "버퍼에 데이터가 들어 있느냐"(지금 버퍼 상태가 1이냐)고 물어보면 레벨 트리거입니다. 1에서 0으로 상태가 변한다든지, 지금 상태가 0이냐고 물어보는 것도 마찬가지입니다.
좀 엉뚱한 방법일 수도 있는데..
메세지 큐를 이용하는 방법도 있을 수 있을 것 같습니다.
(파리 잡는데 대포쏘는 격일 수도 있지만)
블록이 발생되기 직전에 해당 쓰레드가 큐에 자신의 쓰레드 아뒤따위를 붙여서 메세지를 올립니다.
그리고 블록이 풀린 바로 큐에서 자신의 쓰레드 아뒤의 메세지를 지웁니다.
별도로 작성된 스케쥴러는 큐를 감시하다가...
큐에서 일정시간 빠져나가지 않는 메세지가 있다면...
바로 스케쥴을 조정하는 방식이지요...
장점은 스케쥴러가 별도의 프로세스로 작성이 가능하다는 것이고...
단점은 느리고, 다소 무거울 수도 있고... 가끔은 메세지큐를 청소를
해주어야 한다는 ㅋㅋㅋ
위에 보면 /proc/pid/status를 monitoring 하는 것이 overhead가 크다는게 어떤 의미인지 궁금합니다? 제 생각엔 /proc에서 read 하는 작업엔 별로 overhead가 없을 것 같은데. 그런 식으로 처리한게 있는데.
이 부분이 문제가 될 소지가 있나요?
오늘 우리는 동지를 땅에 묻었습니다. 그러나 땅은 이제 우리들의 것입니다.
아직도 우리의 적은 강합니다. 그러나 우리는 그들보다 많습니다.
항상 많을 것입니다.
코드를 보세요...-_-ㅋ그것도다 확실한게 있을 까요? <
코드를 보세요...-_-ㅋ
그것도다 확실한게 있을 까요?
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
이상하군요
런타임때도 그걸 알수 있다는건지
코드에 블럭있는 코드가 있다고 해서 그 쓰레드가
24시간 블럭중인가요?
무슨 생각을 가지고 답변을 달으셨는지 의심스럽네요
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
Block이라는게 정확히 어떤 block을 말씀하시는건지요?1.
Block이라는게 정확히 어떤 block을 말씀하시는건지요?
1. 그냥 프로세스가 좀비되는 것을 말씀하시는건지
2. 아니면 시스템콜 관련 함수에서 (recvfrom같은...) blocking되는 것을 말씀하시는건지.....
3. 아니면 무한루프(Busy loop)에 빠져있는 상태를 말씀하시는건지...
4. pthread_join으로 인한 block을 말씀하시는건지...
5. mutex에의 dead lock상태로 인한 block을 말씀하시는건지...
여기서 블럭을 말하는것은
시스템 호출로 인한 블럭
sleep으로 인한 블럭
뮤텍스로 인한 블럭
일반적인 OS에서 말하는 블럭을 말씀드립니다
그리고
데드락이나 무한 루프를 일반적인 블럭이라고 칭하진 않죠 --;
말 그대로 데드락이나 무한 루프라고 부를뿐
쓰레드 스케줄러에서 블럭된건 스케줄링 안해주지 않습니까?
스케줄링 안해주는 그런 경우를 말합니다
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
흠... ps 해보시면 상태가 'S'로 되는 시점에서 block입니다.
흠... ps 해보시면 상태가 'S'로 되는 시점에서 block입니다.
더욱 밀접한 해상도로 측정은 어려울거 같습니다.
여기서 S는 Sleeping이죠...
/proc/<pid>/status
를 읽어서
"State:" 문구 있는 부분이죠.
프로그램상으로 아는 방법은 없을까요?
ps 내부에에서 그런걸 알아내는 부분이 있을거 같은데
API로는 없나요?
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
/proc/<pid>/status 파일을 읽어셔서 "Stat
/proc/<pid>/status 파일을 읽어셔서 "State: " 항목의 값을 확인해 보세요..
awk 쓰시면 편하겠네요.. 그럼!~ 잘되시길
음.........
사실 윈도우의 IOCP처럼 쓰레드가 sleep 같은걸로 블럭중일때
자동으로 다른 쓰레드를 작동시키는것 처럼
흉내를 내볼까 생각중이었는데
위방법으로는 너무 오버헤드가 큰거 같네요 --;
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
예를 들어 get_thread_state(thread_t *t)란 함수가
예를 들어 get_thread_state(thread_t *t)란 함수가 있어서 이것의 리턴값이 호출하는 순간의 쓰레드 상태를 나타낸다고 하더라도, 부른쪽에서 이 값을 읽어내는 순간에 쓰레드가 여전히 자고 있는지 아니면 깨어났는지는 알 길이 없습니다. 아마도 일종의 이벤트 통지 메커니즘을 쓰레드 상태를 이용해서 구현하려고 하시는 것 같은데, 쓰레드가 블럭된 적이 있는지는 알아낼 수 있지만, 블럭된 중인지 알아내는 방법은 없는 듯 합니다.
그런데, 윈도의 IOCP는 유닉스 select/poll을 구현하기 위해 만든 것이 아닌가요? 그리고 쓰레드가 블럭중일 때 자동으로 다른 쓰레드를 작동시키는 것은 커널 스케줄러가 하는 일 아닌가요. 설명을 좀 부탁드려도 될지...
음 근데.....
select poll -_-; 같은건 절대 아닙니다
방준영님이 아직 윈속 부분은 손 안되셨나보네요
이미 select는 윈속에 존재 하거든요
물론 소켓 구조 자체가 유닉스 계열과 달라서 내부는 조금 다르지만
인터페이스는 거의 비슷합니다
근데 , select같은 부류로 생각을 하셨다니..... 쿄쿄
IOCP 아키텍쳐를 보시면 , 정말 흥미로워 하실거 같습니다
일단 KLDP는 자료실이 없는 관계로 올리진 못하겠고요
데브피아에 VC++쪽 강좌란에 "이기탁"이름으로된
IOCP 강좌가 있을겁니다 4부작으로 되어 있는데
정말 꼭 읽어보셨으면 합니다
거기에 구조및 설명이 자세합니다
맛배기로 IOCP구조를 대충 말씀 드리자면
CPU의 수를 보고 IOCP에 쓰일 쓰레드 풀을 만듭니다 [보통 *2를 하죠]
그리고 소켓으로 오는 자료를 쓰레드 풀에서 recv해 처리를 하게 되는데
만약 쓰레드 풀에 있는 곳에서 sleep같은게 일어나 있지 않는다면
쓰레드 풀에서 한쓰레드만 계속 사용합니다 [한마디로 문맥교환 방지,한 쓰레드만 사용함으로써 스텍 메모리 스와핑도 예방 가능]
sleep이 되어 있다면 쓰레드 풀에서 남아있는 다른 쓰레드를 사용해서
소켓을 처리합니다 [자체적으로 스케줄링합니다,획기적이죠]
절묘하게 큐와 쓰레드풀[스텍방식으로]을 엮어쓰므로써 가장으로 효율적으로
IO를 처리하게해주는 방식입니다
내부적으로는 스와핑이 안되는 OverLapped IO구조체를 사용한다고 본거 같네요)
그리고 보통 select와 poll은 처리 속도를 비교해 봤을적엔
O( n )이라면 IOCP는 O( 1 )이 된다고 합니다
[epoll이나 kqueue하고 속도는 비슷할거 같지만 구조로 본다면 더 나을거 같다는 생각이 들더라고요]
준영님이 이걸 구현하신다면 NetBSD는 농담아니고 서버쪽에서는
최강이 될듯 싶네요 )
그럼
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
IOCP와 select/poll의 차이.
가장 큰 차이는 I/O Completion을 알리는 것이고, select/poll은 I/O Ready
를 알리는 것입니다. 다른 차이는, IOCP의 Thread 사용 및 관리에 있습니다.
IOCP의 가장 큰 목적은 I/O가 빈번히 일어나는 서버가 여러 클라이언트 세션
을 Thread들로 유지함에 따라 발생하는 불필요한 switching cost를 없애기
위한 것이기 때문에, 우선적으로 I/O event 에 따라 thread switching을
하게 됩니다.
위의 방식을 구현하기 위하여 일반적인 Thread Library를 사용하게 되면
switching이 원하지 않는 때에 발생하기 때문에 IOCP 형태를 구현하기가
어렵게 됩니다.
@ IOCP가 무조건 가장 좋은 I/O 처리 구조는 아닙니다. 어디까지나 I/O
가 빈번히 발생하며 동시 세션이 많은 서버에서 좋을 뿐입니다. 어느 수준
이하로 가면 큰 차이가 없으며, 오히려 I/O가 적게 일어나는 서버에서는
Response Time이 커지는 세션이 발생할 수 있습니다.
@ 이러한 Event 기반의 처리 시스템에 대해서는 논문도 있고, 실제로 리눅스
상에서 구현을 하는 경우도 있습니다.
Re: 음 근데.....
이벤트 통지 메커니즘을 레벨 트리거 방식으로 만드느냐 엣지 트리거 방식으로 만드느냐 그 차이 아닌가요.
[quote]이벤트 통지 메커니즘을 레벨 트리거 방식으로 만드느냐 엣지
말은 많이 들어보았는데 두개의 방식이 구체적으로 어떤 것이지요?
음냐 이제야 답변을 해주시는군여 -_-;
그런 상세한 부분은 저야 모르죠 --;
저 아직 코더일뿐입니다 ~ oops
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
Edge Triggered 방식과 Level Triggered 방식..
epoll man페이지에 epoll을 가지고 두 방식의 차이를 설명하고있습니다.
엣지 트리거와 레벨 트리거
엣지 트리거와 레벨 트리거는 원래 전자공학 용어인데, 소프트웨어 분야에도 비슷한 개념을 설명할 때 씁니다. 차이점은 옛지 트리거는 상태의 변화를 탐지하는 반면, 레벨 트리거는 상태의 값을 탐지한다는 것입니다. 예를 들면 버퍼의 상태는 비어있든지(값0), 데이터가 들어있든지(값1) 둘중 하나입니다. 이때 시스템에게 "버퍼에 데이터가 들어 왔느냐"(버퍼 상태가 0에서 1로 변했느냐)고 물어보면 엣지 트리거이고, "버퍼에 데이터가 들어 있느냐"(지금 버퍼 상태가 1이냐)고 물어보면 레벨 트리거입니다. 1에서 0으로 상태가 변한다든지, 지금 상태가 0이냐고 물어보는 것도 마찬가지입니다.
그러면...
select poll은 레벨 트리거나보네요
김치하님의 번역영어로 "수신 저수위값"을 체크하니까요 --;
근데 엣지 트리거나 레벨트리거나 어차피 if으로 간단히 체크하는거 같은 느낌인데 성능차이가 많이 나나요? --;
말씀을 듣고 나니.....
엣지 트리거라면 반드시 논블럭을 써야 할거 같은 느낌이...
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
Re: 그러면...
예, 맞습니다. 반면 윈도 IOCP는 비동기 입출력의 상태가 완료로 변하는 순간 포트에 통지되니까 엣지 트리거 방식이죠. 또한가지는 select/poll과 IOCP를 단순 비교한 것은 제 착각이었다는 것... 8)
select/polll과 kqueue를 놓고 보면 같은 레벨 트리거라도 성능차가 확연하죠. 윈도가 성능상에서 앞선다면 비동기 입출력 덕택이 아닐까요.
예, 하지만 어차피 블럭 아니면 논블럭인데 블럭을 쓸 수는 없으니까요. 8)
다음은 참고 자료입니다. 세상은 넓고 배울 것은 너무나 많군요...
http://www.kegel.com/c10k.html
http://www.sysinternals.com/ntw2k/info/comport.shtml
http://www.kegel.com/dkftpbench/nonblocking.html
http://www-users.itlabs.umn.edu/classes/Fall-2002/csci4061/slides/l12b.html
깜박했는데...
네... 좋은 정보 감사하고요 :D
근데 깜박했는데 IOCP처럼 sleep인지 체크를 하고 sleep이면
자체 쓰레드를 스케줄링하는 방법은 유닉스 계열에서는 없는지여?
주목적이 이거였는데 .....
승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스
좀 엉뚱한 방법일 수도 있는데..메세지 큐를 이용하는 방법도 있을 수
좀 엉뚱한 방법일 수도 있는데..
메세지 큐를 이용하는 방법도 있을 수 있을 것 같습니다.
(파리 잡는데 대포쏘는 격일 수도 있지만)
블록이 발생되기 직전에 해당 쓰레드가 큐에 자신의 쓰레드 아뒤따위를 붙여서 메세지를 올립니다.
그리고 블록이 풀린 바로 큐에서 자신의 쓰레드 아뒤의 메세지를 지웁니다.
별도로 작성된 스케쥴러는 큐를 감시하다가...
큐에서 일정시간 빠져나가지 않는 메세지가 있다면...
바로 스케쥴을 조정하는 방식이지요...
장점은 스케쥴러가 별도의 프로세스로 작성이 가능하다는 것이고...
단점은 느리고, 다소 무거울 수도 있고... 가끔은 메세지큐를 청소를
해주어야 한다는 ㅋㅋㅋ
쓰레드 레벨에서 지원하는 보다 빠른 큐가 있다면 그걸 사용하시는 편이...
헉 생각해보니 그럴 바에야...전역변수를 플레그 처럼 사용하는 방법도 있네요...
그게 낳겠군요...
There is no spoon. Neo from the Matrix 1999.
위에 보면 /proc/pid/status를 monitoring 하는 것이
위에 보면 /proc/pid/status를 monitoring 하는 것이 overhead가 크다는게 어떤 의미인지 궁금합니다? 제 생각엔 /proc에서 read 하는 작업엔 별로 overhead가 없을 것 같은데. 그런 식으로 처리한게 있는데.
이 부분이 문제가 될 소지가 있나요?
오늘 우리는 동지를 땅에 묻었습니다. 그러나 땅은 이제 우리들의 것입니다.
아직도 우리의 적은 강합니다. 그러나 우리는 그들보다 많습니다.
항상 많을 것입니다.
댓글 달기