2012-02-26 2 views
2

나는 TCP 소켓을 사용하는 C/Linux 채팅 서버를 가지고있다. libev를 사용할 때 소켓에 대해 한 번씩 이벤트를 읽는 ev_io 와처를 만들 수 있습니다. 뭔가 같은 :Libev - 입출력 콜백

ev_io* new_watcher = (ev_io*)malloc(sizeof(ev_io)); 

//initialize the watcher 
ev_init(new_watcher, read_cb); 

//set the fd and event to fire on write 
ev_io_set(new_watcher, watcher->fd, EV_READ); 

//start watching 
ev_io_start(loop, new_watcher); 

하고 읽을 수있는 데이터가있을 때 읽기 이벤트 만 발생하기 때문에이 잘 작동합니다. 그러나 필자는 쓰기 이벤트가 다르기 때문에 끊임없이 쓰기 때문에 이벤트를 다르게 처리해야합니다. 이 문제를 해결하기 위해 필자는 write_callback을 사용하여 데이터를 쓸 준비가되었을 때만 데이터를 기록 할 수있는 ev_io 관찰자를 만든 다음 write_callback이 메시지를 보낸 후 watcher를 삭제합니다.

즉, 메시지를 처리해야 할 때마다 쓰기 감시자를 할당, 초기화, 설정, 감시, 해제 및 할당 해제 중임을 의미합니다. 나는 이것을 잘못하고 비효율적으로 다루고 있을지도 모른다고 걱정한다.

libev에서 write_callback 이벤트를 처리하는 가장 좋은 방법은 무엇입니까?

미리 감사드립니다.

답변

0

할당이 약간의 오버 헤드를 추가 할 수 있습니다. malloc 대신 정적 변수를 사용하거나 이벤트 루프가 끝난 후 한 번만 malloc을 사용할 수 있습니다. 쓰기 전에 설정하고 성공 후 설정을 해제해야합니다. 하지만 그렇습니다. 그렇게해야합니다.

0

나는이 상황을 해결하기 위해 버퍼에 포인터와 길이를 사용하는 데이터를 쓰는 기능을 가지고있었습니다. 포인터 W 길이를 큐 데이터 구조에 저장하고 쓰기 이벤트를 사용 가능하게합니다.

쓰기 이벤트 콜백이 발생하면 쓰기 큐가 있는지 확인하여 보류중인 쓰기가 있는지 확인합니다. 어떤 것이 있으면 대기열에서 다음 대기중인 쓰기를 취하여 파일 설명자에 씁니다. 그런 다음 쓰기 콜백이 종료되기 바로 전에 보류중인 쓰기 대기열이 비어 있는지 확인합니다. 그렇다면 쓰기 이벤트를 사용 불가능하게합니다.

읽기/쓰기 이벤트 객체를 전역 변수로 만들면 할당되고 해제됩니다. 기록 할 데이터가 있음을 알 때마다 쓰기 이벤트를 활성화하고 기록 할 데이터가 더 이상 없으면 비활성화합니다.

내 코드는 위의 설명보다 약간 복잡하지만 여기를 클릭하면 링크를 게시 할 수 있습니다. 내가 특별히 얘기하는 코드는 aiofd.h와 aiofd.c (aiofd == 비동기 I/O 파일 설명자)입니다. https://bitbucket.org/wookie/cutil/

이 정보가 도움이되기를 바랍니다.

4

Easy, ev_io_stop도 있습니다. 쓸 일이 없으면 write watcher를 시작하지 않고 전체 버퍼를 썼을 때 콜백 내부에서 ev_io_stop을 호출합니다.

데이터가 작고 너무 자주 wirte하지 않기 때문에 드물게 trhe 쓰기 버퍼가 오버 플로우되지 않는 일반적인 경우에는 데이터를 직접 쓰는 것이 좋습니다 (감시자가 아닌 경우). 활성 상태) 데이터를 버퍼링하고 쓰기 워처를 완전히 쓸 수 없다면 시작합니다.

위의 가정하에, 이것은 거의 write watcher를 시작할 필요가 없음을 의미합니다. 단점은 코드가 훨씬 복잡하므로 많은 경우에 버퍼를 작성하기 위해 데이터를 추가하고, 버퍼가 완전히 작성된 경우에는 감시자를 시작하고 관찰자는 버퍼를 완전히 정지하는 것으로 시작하는 것이 가장 좋습니다.