Ключевые слова:select, IO, (найти похожие документы)
_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Andrew B. Sapozhnikov 2:5020/400 18 Feb 99 13:36:44
Subj : non-blocking I/O
________________________________________________________________________________
From: "Andrew B. Sapozhnikov" <[email protected]>
Alex Tutubalin wrote:
> Vladimir A. Butenko wrote:
> > > Почему поллим ? select()'им. Может и оверхед, но думаю что существенно
> > меньший,
> > > чем при реализации non-blocking I/O через threads :)
> > Так в тредах-то зачем нон-блокинг? Пусть блокируются. И никаких там на
> > этот i/o нет расходов лишних.
> Вы не поняли. Речь ровно об обратном. Для реализации non-blocking I/O
> делается так - на каждую блокирующую операцию запускается thread,
> которая и блокируется на ней до получения результата. С non-blocking
> я, естественно, перебрал, а async I/O где-то (уже не помню где) я видел
> сделанный таким образом
Hапример в Squid-е. К несчастью никак иначе асинхронный ввод вывод в
задаче не сделать. Select для регулярных файлов по-пионерски выдает
"всегда готов!", а non-blocked I/O в точности равен blocked.
Попробуй для примера:
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc,char *argv[]) {
int h,retval;
fd_set rfds;
struct timeval tv;
char buf[4096];
if(argc!=2) {
fprintf(stderr,"usage: %s <filename>\n",argv[0]);
return 2;
}
h=open(argv[1],O_RDONLY|O_NONBLOCK,0);
if(h==-1) {
perror("open:");
return 1;
}
FD_ZERO(&rfds);
FD_SET(h, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(h+1, &rfds, NULL, NULL, &tv);
printf("SELECT: %sready\n",retval?"":"not ");
while(1) {
int nread=read(h,buf,4096);
if(nread==-1) {
if(errno==EAGAIN) printf("EAGAIN\n");
else break;
} else if(nread==0) break;
FD_SET(h, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
retval = select(h+1, &rfds, NULL, NULL, &tv);
printf("SELECT: %sready\n",retval?"":"not ");
}
return 0;
}
И натрави его для примера на крупный файл на дискетке. Hи одной
неготовности и ни одного EAGAIN-а не будет. Сигнал SIGIO, кстати,
регулярными файлами тоже не генерируется. А в open-е каждом read-е
задача будет проводить изрядно времени. Та же песня с файлами на NFS.
И как, позвольте спросить, задаче использовать это время "с умом",
скажем Squid может обслуживать чей-то другой запрос пока идет
чтение файла из кэша... Можно конечно и без тредов это решить.
Оракл например создает несколько процессов "writer-ов" с коими
общается через shared memory.
Best regards, Andrew Sapozhnikov.
--- ifmail v.2.14dev2 * Origin: ICB (2:5020/400@fidonet)