nfds文件类型有哪些|如何调用Linux内核函数

|

① 如何调用linux内核函数

注意看这个文件sysdeps/unix/sysv/linux/syscalls.list里面记录着系统调用的名字和一些属性,具体我也没有研究过,不懂。再看select的实现,很让人惊讶,一旦使用,结果就是“报错“。int__select (nfds, readfds, writefds, exceptfds, timeout)int nfds;fd_set *readfds;fd_set *writefds;fd_set *exceptfds;struct timeval *timeout;{__set_errno (ENOSYS);return -1; }libc_hidden_def (__select)stub_warning (select)weak_alias (__select, select)这是因为glibc并没有实现系统调用,而是调用系统调用,更进一步,连调用系统调用都没有一个个实现,而是使用了通用的办法,理由很简单,所有的系统调用在linux内核头文件里都能找到,所有的系统调用参数类型就那么几种,参数个数也是有限的,因此没有必要针对所有的系统调用一一封装,于是就有了这个list文件,自动生成调用系统调用的函数,如果生成失败,也就是你看到的“报错”。符号是有强弱的,当自动生成成功的时候,“报错”的弱符号就被忽略了。当你在glibc中找到一个系统调用的封装源码,是以下原因,1. 编译的目标系统不支持这个系统调用,所以自己用另一种方式实现了。2. 这个系统调用无法使用通用的自动生成方式生成,用特化的方式覆盖。3. 针对这个系统调用做了特别的优化。4. 其它可能的原因。具体可以留意SYSCALL, PSEUDO, DO_CALL, INLINE_CALL 等名字这两个文件是重点所在sysdeps/unix/i386/sysdep.hsysdeps/unix/i386/sysdep.S要搞清楚具体的自动生成过程,恐怕得研究glibc自身的编译过程了

② 如何使用windows网络编程select

1. select系统调用select系统调用是用来让我们的程序监视多个文件描述符的状态变化的。程序会停在select这里等待,直到被监视的文件描述符有某一个或多个发生了状态改变。select()的机制中提供一fd_set的数据结构,实际上是一long类型的数组,每一个数组元素都能与一打开的文件句柄建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪些Socket或文件可读可写。select函数原型:#include <sys/select.h> #include <sys/time.h>#include <sys/types.h>#include <unistd.h>int select(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, const struct timeval * timeout);ndfs:select监视的文件句柄数,视进程中打开的文件数而定,一般设为要监视各文件中的最大文件描述符值加1。readfds:这个文件描述符集合监视文件集中的任何文件是否有数据可读,当select函数返回的时候,readfds将清除其中不可读的文件描述符,只留下可读的文件描述符。writefds:这个文件描述符集合监视文件集中的任何文件是否有数据可写,当select函数返回的时候,writefds将清除其中不可写的文件描述符,只留下可写的文件描述符。exceptfds:这个文件集将监视文件集中的任何文件是否发生错误,其实,它可用于其他的用途,例如,监视带外数据OOB,带外数据使用MSG_OOB标志发送到套接字上。当select函数返回的时候,exceptfds将清除其中的其他文件描述符,只留下标记有OOB数据的文件描述符。timeout:本次select()的超时结束时间。这个参数至关重要,它可以使select处于三种状态:(1)若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;(2)若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;(3)timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。函数的返回值:正值:表示监视的文件集中有文件描述符符合要求零值:表示select监视超时负值:表示发生了错误,错误值由errno指定。宏操作:FD_ZERO(fd_set *set): 用来清除描述词组set的全部位FD_SET(int fd,fd_set*set): 用来设置描述词组set中相关fd的位FD_ISSET(int fd,fd_set *set): 用来测试描述词组set中相关fd 的位是否为真FD_CLR(inr fd,fd_set* set): 用来清除描述词组set中相关fd 的位注意事项:(1)对于可写性的检查,最好放在需要写数据的时候进行检查。如果和可读性放在同一个地方进行检查,那么select很可能每次都会因为可写性检查成功而返回。 (2)select()调用会清空传递给它的集合参数中的内容,也就是会清空readfds、writefd、exceptfds这三个指针参数所指定的描述符集合。因此,在每次调用select()之前,必须重新初始化并把需要监视的描述符填写到相应的描述符集合中。select()调用也会清空timeout指针所指向的struct timeval结构,所以在每次调用select()之前也要重新填充timeout指针所指向的struct timeval结构。


赞 (0)