입출력 여러개, select함수, timeout에 대해서 질문입니다.
글쓴이: kingchobo / 작성시간: 금, 2005/05/13 - 10:19오전
갑자기 머리가 복잡해져서 여쭙니다.
select함수를 사용해서 입출력장치 여러개를 제어합니다.
그리고
각각의 장치는 마스터쪽에서 보내는 명령어에 대해
어느 일정 시간 내에 대답을 해야 합니다.
예를 들어 1초안에 대답안하면 전송오류로 생각하는 제어모듈이 장치 3개를 제어하고 있습니다.
이럴경우 select함수내의 timeout값을 1초로 해서 이용한다면
첫번째 fd에서 1초 기다리고, 그 다음 fd에서 1초, 다음 fd에서 1초
이렇게 기다리게 되는 거잖아요?
결국엔 마지막 fd는 3초를 기다리게 되는거 아니겠나요?
이는 실시간성이 전혀 보장 되지 않지 않습니까?
저런 장치 제어 모듈을 구현하기 위해
select나 epoll을 사용한다는건 애당초 안되는 건가요?
아니면 select내의 timeout값을 이용하는 것은 여러개의 장치일때는 의미가 없는건가요?
다른방식의 시간 check가 필요한가요?
고수분들의 고견 부탁드립니다.
Forums:
select는 stream-based fd 에만 유용한걸로 알고 있고요.
select는 stream-based fd 에만 유용한걸로 알고 있고요.
timeout은 그런 의미가 아니라 전체 1초 동안에 셋중에 어떤 event가 발생하지
않으면 timeout이 됩니다.
---------
간디가 말한 우리를 파괴시키는 7가지 요소
첫째, 노동 없는 부(富)/둘째, 양심 없는 쾌락
셋째, 인격 없는 지! 식/넷째, 윤리 없는 비지니스
이익추구를 위해서라면..
다섯째, 인성(人性)없는 과학
여섯째, 희생 없는 종교/일곱째, 신념 없는 정치
아하 타임아웃에대해 잘못이해하고 있었군요.
아. 그런거였군요. 얇팍한 지식. 으. :oops:
그럼 동시에 타임아웃내의 시간동안 event가 동시에 두개 발생하면 어떻게
되는 건가요?
그럼 또 복잡해지는데?
Re: 아하 타임아웃에대해 잘못이해하고 있었군요.
그러면 select() 반환시 두개 이상의 fd가 세트되므로 FD_ISSET으로 확인하면 되겠지요.
--
익스펙토 페트로눔
Re: 아하 타임아웃에대해 잘못이해하고 있었군요.
근데 select()는 이벤트가 발생하면 실행이 될텐데 2, 3개의 이벤트 발생은 무시되어야 하지 않나요?
물론 FD_ISSET()은 하나의 정상적인 경우에도 사용을 해야 하는 거구요.
FD_ISSET()없으면 select()는 사용 못합니다.
sleep()대용으로나 쓸까나.
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
select 가 block 된 상태에서 이벤트가 들어오면 그땐 반환 되는
select 가 block 된 상태에서 이벤트가 들어오면 그땐 반환 되는게 1개가 맞습니다.
하지만, 다른 작업을 하고 있는 도중에 이벤트가 여러개 발생해서 대기중일대 select 함수를 call 하면 그때까지 처리되지 않은 이벤트 모두가 반환됩니다.
그때 select 의 리턴값으로 몇개의 이벤트가 반환됐는지 알 수 있습니다.
select man 페이지는 자세히 읽어보시면 도움이 될 듯 하군요.
근데... 어짜피 FD_ISSET()은 loop문을 이용해서 다 검사하지
근데... 어짜피 FD_ISSET()은 loop문을 이용해서 다 검사하지 않나요?
앞서 한 얘기는 동시에 select() 하부의 코드가 실행 중일 때는 무시 되어야 하는게 아닌가 하는 그런 문맥의 흐름인데...
저도 약간 착각한 부분이 있을 지도.
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
Re: 아하 타임아웃에대해 잘못이해하고 있었군요.
이 글을 보니 select 가 timeout 시간까지 무조건 기다렸다가
그 시간 사이에 발생한 모든 이벤트를 알려주는 것으로 오해하신것 같은데, select 는 이벤트가 발생하면 즉시 반환해 주며, 다만 timeout 시간이 지나도 이벤트가 발생하지 않을시에 timeout이 됐다는 리턴값을 반환할 뿐입니다.
그러므로 3개에 대한 각각 1초내 응답이 됐는지를 알기 위해서는 select 만으로 해결이 불가능합니다. 3개 각각에 대해 요청 시각을 기록한 후 그 시간과 현재 시각을 비교해서 요청에대한 응답이 timeout 이 됐는지 확인하셔야 합니다.
각각의 fd 에 따로 따로 timeout 을 적용시키려면 ssehoony
각각의 fd 에 따로 따로 timeout 을 적용시키려면 ssehoony 님의 말씀처럼 요구에 맞게 구현을 더 해야 합니다.
이런 걸 좀 편하게 해주는 라이브러리도 있습니다. libevent 라는 것인데요. 개별 timeout 도 적용되고 콜백 호출을 해주는 형태이면서 select, poll, epoll, kqueue 등을 감싸주는 API 를 제공해줘서 잘 사용하고 있습니다.
[quote]이 글을 보니 select 가 timeout 시간까지 무조건
그렇다면 3개의 이벤트가 순차적으로 발생했을때. 1번 이벤트 2번 이벤트 3번 이벤트라 칭하고
1번 이벤트가 먼저 발생했다하고, select를 빠져 나와서 그 이벤트를 처리하는동안(이 시간이 좀 길다 치면요.) 2번 3번 이벤트가 들어왔다면 어떻게 되는 거지요? 2번 3번 이벤트는 무시되나요?
[quote="ssehoony"]select 가 block 된 상태에서
음.. 여기 답변이 있는데 ^^;;
select가 블록된 상태라는 말의 의미가 와닿지 않아요.
select가 블록된상태라는 말의 의미가 무엇인지요?
이벤트 발생을 대기하는 기간 상태를 말씀하시는 건가요?
그렇다면 타임아웃을 0으로 했을때는 어떤 fd에 이벤트가 발생했는지만 체크하고 넘어가는 건가요?
음 그리구.
만일 블록이라는 의미가 그거라면
시나리오를 한번 생각하면
일단
1. select가 블록 되어 있다.
2. 1번 이벤트 발생
3. select는 이벤트 1개를 반환하면서~ 리턴
4. 해당 루틴 수행 (좀 길게)
5. 4번 루틴 수행동안 2번, 3번 이벤트 발생~
6. 2번, 3번 이벤트는 대기
7. 다음 select 수행시 2번, 3번에 대한 이벤트를 리턴
이런 시나리오인가요?
또. 제가 본 man페이지는 이렇습니다.
그런얘기 안나와염.. ㅜ.ㅜ
Re: select가 블록된 상태라는 말의 의미가 와닿지 않아요.
네. 위에 말씀하신 대로 작동합니다.
여기에 조금 더 시나리오를 추가 하면
8. select 블록 (timeout 을 5초로 셋팅)
9. 5초동안 이벤트 발생하지 않음
10. select 가 0을 리턴
11. 잠시 다른 일
12. select 블록 (timeout을 0으로)
13. 미처리이벤트가 없으므로 select 는 즉시 0 반환
14. 잠시 다른 일
15. 14번을 하는 도중 이벤트 2개 발생
16. select 블록 (timeout 을 0으로)
17. 15번에서 발생한 이벤트 2개 반환
이정도가 익숙해 지시면
read 이벤트와 write 이벤트에 대한 구분도 필요하겠군요.
소켓 통신시에는 write 이벤트에 대해서도 꼭 알아두셔야 합니다.
[code:1]18. 타임아웃 포인터를 NULL(무한대기)
select() 호출하면?
1. 기본적으로 block됨
2. 그렇다면, 탈출(리턴)해야 하는데...언제 탈출하나?
2-1 select()호출시 입력 파라메터 값이 잘못됨
2-2 한개 이상의 이벤트(In,Out, Exception) 발생
2-3 지정한 시간이 초과(타임아웃)
- 이 시간을 tv_sec =0, tv_usec=0으로 하여 마치 non-block인것처럼 간주할 수 있으나, 정확히는 타임아웃이다.
2-4 타임아웃 또는 이벤트를 대기중인데, 시그널이 발생
* 위에서 다른 분들이 좋은 의견 많이 있었습니다.
* 질문자 님의 경우, 매 장비별 별도 타이머( 또는 타임관리 루틴)가 필요하리라 예상되며,
멀티쓰레드를 이용하거나 멀티프로세스로 코딩하시는 것이 더 좋은 선택으로 보입니다.
* bugiii님이 추천하신, select(), poll()등 일반적인 *NiX 시스템의 IO이벤트 처리루틴과, 특정 시스템에 제한되는 특성을 가진 epoll, kqueue, /dev/poll등을 잘~ wrapping한 libevent()를 사용하시는 것도 좋습니다.
* 좋은 프로그램 많이 만드세요.
코드로 보면 대략ret=select(...);if (ret >
코드로 보면 대략
ret=select(...);
if (ret > 0 ) {...} // 이벤트 발생(IO, exception)
else if ( ret < 0 ) {...} // 에러나 시그널
else {...} // ret == 0 , 타임아웃
이래야 한다는....
음 좋은 답변들이 또 있었군요.
그랬던 것인가요?
음 멀티 쓰레드가 필요했던거군요.
어디 그렇게 구현된
샘플예제 없나요?
모 어렵게 생각하지 마시고, 장비 하나에 대해 처리하는 것을 함수 수준으
모 어렵게 생각하지 마시고, 장비 하나에 대해 처리하는 것을 함수 수준으로 작성하신 다음 즉, 1개에 대해서 잘 만드시고요.
이를 쓰레드(프로세스)로 다수개 생성하시고, 쓰레드라면 쓰레드들의 상태정보를 글로벌 변수로 놓고, 프로세스라면 공유메모리등 IPC메카니즘으로 동기화하여
이를 모니터링하는 쓰레드(프로세스) 하나 더 만드시면 되겠습니다.
* 쓰고보니, 말만 쉽군요. 전형적인 서버프로그램 유형으로 시작해보세요.
서버유형은 스티븐스님의 UNP시리지에 많이 있겠군요.
댓글 달기