当前位置:嗨网首页>书籍在线阅读

25-练习

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

63.7 练习

63-1.  修改程序清单63-2(poll_pipes.c)中的程序,使用poll()来取代select()。

63-2.  编写一个echo服务器(见 60.2 节和60.3节),使其能够同时处理TCP和UDP客户端。要做到这一点,服务器端必须创建一个 TCP 监听套接字和一个UDP监听套接字,然后采用本章中所描述的其中一种技术来同时监视这两个套接字。

63-3.  63.5节中提到select()不能用来同时等待信号和文件描述符,并提出采用信号处理例程加管道的方式来解决。当一个程序需要在文件描述符和System V的消息队列上等待输入时,也会出现相似的问题(因为System V消息队列并不使用文件描述符)。一种解决方法是使用fork()生成一个单独的子进程,子进程从队列中拷贝每条消息到管道中,并且也将由父进程所监视的文件描述符一并拷贝。采用这种方法编写一个程序,通过select()来监视终端和消息队列上的输入。

63-4.  63.5.2节中介绍的self-pipe技巧中,最后一步表明程序应该首先将管道中的所有数据读取完毕,之后再执行信号处理的操作。如果这两步颠倒的话会出现什么问题?

63-5.  修改程序清单63-9中的程序(self_pipe.c),使用poll()来取代select()。

63-6.  编写一个程序使用epoll_create()来创建一个epoll实例,然后立刻调用epoll_wait()在之前返回的文件描述符上等待。在这种情况下,传递给epoll_wait()的兴趣列表是空的,此时会出现什么情况?这么做有什么用处?

63-7.  假设我们有一个epoll文件描述符,它正在监视的多个文件描述全部都一直处于就绪态。如果我们执行一系列的epoll_wait()调用,其中参数maxevents比处于就绪态的文件描述符数量小很多(例如,maxevents为1)。在每次调用之间,我们并不在处于就绪态的文件描述符上执行全部的I/O操作。此时在每次调用中epoll_wait()返回的描述符是什么?编写一个程序来确定答案。(基于这个实验的目的,在epoll_wait()调用之间不执行任何I/O操作就足够了。)为什么这种行为会很有用?

63-8.  修改程序清单63-3中的程序(demo_sigio.c),用实时信号取代SIGIO。修改信号处理例程,使其接受一个siginfo_t参数,并打印出这个结构体的si_fd和si_code字段。

①译者注:本章之前都是用文件描述符(file descriptor)来表示打开了某个文件,这一段又冒出来个文件描述(file description),而文件描述和文件描述符之间还有着关联。其实是这样的:文件描述(file description)表示的是一个打开文件的上下文信息(大小、内容、编码等与文件有关的信息),可以比喻为一个抽屉,这部分内容实际上是由内核来管理的。而用户空间的应用程序如果要操作文件怎么办。就是通过open()这样的系统调用向内核请求,然后内核分配给用户空间一个文件描述符(file descriptor)。这个文件描述符可以比喻为抽屉的把手(handle之所以翻译为“句柄”,这就是原因),有了这个把手(文件描述符),用户就可以操作抽屉(文件描述)里的内容了。但是,一个抽屉可以有多个把手(即文件描述可以对应多个文件描述符),只有当所有的把手(文件描述符)都关闭了,内核就知道此时没有用户空间的程序要用这个抽屉了(文件描述),那么就把它回收。 文件描述实际上是内核中的一个数据结构,而用户空间中的文件描述符只不过是一个整数,epoll的兴趣列表实际关注的是内核中的数据结构。所以作者在这里改进了一下之前的结论,说得更细,更准确,也符合这一节的主题“深入探究epoll的语义”。