当前位置: 首页 > news >正文

怀化市住房与城乡建设厅网站书店网站建设需求分析调研表

怀化市住房与城乡建设厅网站,书店网站建设需求分析调研表,网站如何做360优化,wordpress 角色等级系统调用dup和dup2能够复制文件描述符。dup返回新的文件文件描述符#xff08;没有用的文件描述符最小的编号#xff09;。dup2可以让用户指定返回的文件描述符的值#xff0c;如果需要#xff0c;则首先接近newfd的值#xff0c;他通常用来重新打开或者重定向一个文件描述… 系统调用dup和dup2能够复制文件描述符。dup返回新的文件文件描述符没有用的文件描述符最小的编号。dup2可以让用户指定返回的文件描述符的值如果需要则首先接近newfd的值他通常用来重新打开或者重定向一个文件描述符。 他的原型如下 #include unsitd.h int dup(int oldfd); int dup2(int oldfd,int newfd); dup 和dup2都是返回新的描述符。或者返回-1并设置 errno变量。新老描述符共享文件的偏移量位置、标志和锁但是不共享close-on-exec标志。 相信大部分在Unix/Linux下编程的程序员手头上都有《Unix环境高级编程》(APUE)这本超级经典巨著。作者在该书中讲解dup/dup2之前曾经讲过“文件共享”这对理解dup/dup2还是很有帮助的。这里做简单摘录以备在后面的分析中使用 Stevens said: (1) 每个进程在进程表中都有一个记录项每个记录项中有一张打开文件描述符表可将视为一个矢量每个描述符占用一项。与每个文件描述符相关联的是    (a) 文件描述符标志。    (b) 指向一个文件表项的指针。 (2) 内核为所有打开文件维持一张文件表。每个文件表项包含    (a) 文件状态标志(读、写、增写、同步、非阻塞等)。    (b) 当前文件位移量。    (c) 指向该文件v节点表项的指针。 图示    文件描述符表    ------------ fd0 0   | p0 ------------- 文件表0 --------- vnode0    ------------ fd1 1   | p1 ------------- 文件表1 --------- vnode1    ------------ fd2 2   | p2    ------------ fd3 3   | p3    ------------ ... ... ... ...    ------------ 一、单个进程内的dup和dup2 假设进程A拥有一个已打开的文件描述符fd3它的状态如下 进程A的文件描述符表(before dup2)    ------------ fd0 0   | p0    ------------ fd1 1   | p1 ------------- 文件表1 --------- vnode1    ------------ fd2 2   | p2    ------------ fd3 3   | p3 ------------- 文件表2 --------- vnode2    ------------ ... ... ... ...    ------------ 经下面调用 n_fd dup2(fd3, STDOUT_FILENO);后进程状态如下 进程A的文件描述符表(after dup2)    ------------ fd0 0   | p0    ------------ n_fd 1   | p1 ------------    ------------               \ fd2 2   | p2                  \    ------------                 _\| fd3 3   | p3 ------------- 文件表2 --------- vnode2    ------------ ... ... ... ...    ------------ 解释如下 n_fd dup2(fd3, STDOUT_FILENO)表示n_fd与fd3共享一个文件表项(它们的文件表指针指向同一个文件表项)n_fd在文件描述符表中的位置为 STDOUT_FILENO的位置而原先的STDOUT_FILENO所指向的文件表项被关闭我觉得上图应该很清晰的反映出这点。按照上面的解释我们就可以解释CU中提出的一些问题 (1) dup2的第一个参数是不是必须为已打开的合法filedes -- 答案必须。 (2) dup2的第二个参数可以是任意合法范围的filedes值么 -- 答案可以在Unix其取值区间为[0,255]。 另外感觉理解dup2的一个好方法就是把fd看成一个结构体类型就如上面图形中画的那样我们不妨把之定义为 struct fd_t { int index; filelistitem *ptr; }; 然后dup2匹配index修改ptr完成dup2操作。 在学习dup2时总是碰到“重定向”一词上图完成的就是一个“从标准输出到文件的重定向”经过dup2后进程A的任何目标为STDOUT_FILENO的I/O操作如printf等其数据都将流入fd3所对应的文件中。下面是一个例子程序 #define TESTSTR Hello dup2\n int main() {         int     fd3; fd3 open(testdup2.dat, 0666);         if (fd 0) {                 printf(open error\n);                 exit(-1);         } if (dup2(fd3, STDOUT_FILENO) 0) {                        printf(err in dup2\n);         }         printf(TESTSTR);         return 0; } 其结果就是你在testdup2.dat中看到Hello dup2。 二、重定向后恢复 CU上有这样一个帖子就是如何在重定向后再恢复原来的状态首先大家都能想到要保存重定向前的文件描述符。那么如何来保存呢象下面这样行么 int s_fd STDOUT_FILENO; int n_fd dup2(fd3, STDOUT_FILENO); 还是这样可以呢 int s_fd dup(STDOUT_FILENO); int n_fd dup2(fd3, STDOUT_FILENO); 这两种方法的区别到底在哪呢答案是第二种方案才是正确的分析如下按照第一种方法我们仅仅在表面上保存了相当于fd_t按照我前面说的理解方法中的index而在调用dup2之后ptr所指向的文件表项由于计数值已为零而被关闭了我们如果再调用dup2(s_fd, fd3)就会出错(出错原因上面有解释)。而第二种方法我们首先做一下复制复制后的状态如下图所示: 进程A的文件描述符表(after dup)    ------------ fd0 0   | p0    ------------ fd1 1   | p1 ------------- 文件表1 --------- vnode1    ------------                 /| fd2 2   | p2                /    ------------             / fd3 3   | p3 ------------- 文件表2 --------- vnode2    ------------          / s_fd 4   | p4 ------/    ------------ ... ... ... ...    ------------ 调用dup2后状态为 进程A的文件描述符表(after dup2)    ------------ fd0 0   | p0    ------------ n_fd 1   | p1 ------------    ------------               \ fd2 2   | p2                 \    ------------                _\| fd3 3   | p3 ------------- 文件表2 --------- vnode2    ------------ s_fd 4   | p4 -------------文件表1 --------- vnode1    ------------ ... ... ... ...    ------------ dup(fd)的语意是返回的新的文件描述符与fd共享一个文件表项。就如after dup图中的s_fd和fd1共享文件表1一样。 确定第二个方案后重定向后的恢复就很容易了只需调用dup2(s_fd, n_fd);即可。下面是一个完整的例子程序 #define TESTSTR Hello dup2\n #define SIZEOFTESTSTR 11 int main() {         int     fd3;         int     s_fd;         int     n_fd; fd3 open(testdup2.dat, 0666);         if (fd3 0) {                 printf(open error\n);                 exit(-1);         } s_fd dup(STDOUT_FILENO);         if (s_fd 0) {                 printf(err in dup\n);         } n_fd dup2(fd3, STDOUT_FILENO);         if (n_fd 0) {                 printf(err in dup2\n);         }         write(STDOUT_FILENO, TESTSTR, SIZEOFTESTSTR);   if (dup2(s_fd, n_fd) 0) {                 printf(err in dup2\n);         }         write(STDOUT_FILENO, TESTSTR, SIZEOFTESTSTR);         return 0; } 注 意这里我在输出数据的时候我是用了不带缓冲的write库函数如果使用带缓冲区的printf则最终结果为屏幕上输出两行Hello dup2而文件testdup2.dat中为空原因就是缓冲区作怪由于最终的目标是屏幕所以程序最后将缓冲区的内容都输出到屏幕。 三、父子进程间的dup/dup2 由fork调用得到的子进程和父进程的相同文件描述符共享同一文件表项如下图所示 父进程A的文件描述符表    ------------ fd0 0   | p0    ------------ fd1 1   | p1 ------------- 文件表1 --------- vnode1    ------------                            /|\ fd2 2   | p2                             |    ------------                            |                                                | 子进程B的文件描述符表                |    ------------                             | fd0 0   | p0                             |    ------------                             | fd1 1   | p1 ---------------------|    ------------ fd2 2   | p2    ------------ 所以恰当的利用dup2和dup可以在父子进程之间建立一条“沟通的桥梁”。这里不详述。 四、小结 灵活的利用dup/dup2可以给你带来很多强大的功能花了一些时间总结出上面那么多不知道自己理解的是否透彻只能在以后的实践中慢慢探索了。
http://www.pierceye.com/news/92652/

相关文章:

  • wordpress 导入主题网站建设优化广告流量
  • 网店装修网站房屋装修设计费一般多少
  • 微信公众平台制作网站设计网站页面要怎么切图
  • 个人网站 备案 类型小红书笔记推广
  • 门户网站怎么创建网页制作步骤php
  • 六师五家渠市建设局网站wordpress 定时发布插件
  • 深圳外贸网站外贸网站建设安阳网站建设服务
  • wdcp 网站建设做民宿推广都有哪些网站
  • 常见的网站开发环境网站建设的结构
  • 贵阳网站推广优化公司做网站的公司搞什么活动
  • 安徽平台网站建设制作坪山网站设计的公司
  • 如何做挂qq的网站2017网站建设
  • wordpress语言切换网站保定广告设计公司
  • 做网站需要走公司吗运行一个网站要多少钱
  • 怎样可以免费做网站wap网站软件
  • 织梦手机网站免费模板漳州城乡建设局网站
  • 厦门建设网站的公司php除了写网站吗
  • 如何做全网影视网站居然之家装修公司怎么样
  • 佛山网站建设公司哪家最好万能软文范例800字
  • 网站排名优化如何做wordpress 免费版广告
  • 拓客网站建设建易网官网
  • 网站目录链接怎么做的建网站pc版 (报价)
  • 北京网站制作业务如何开展做网站海报
  • 网站的设计方法有哪些互动网络游戏公司网站建设
  • 公司网站开发制作公司国内重大新闻2022
  • 搜索引擎排名网站北京到广州快递要几天
  • 制作网站怎么制作html网站 下载
  • 深圳网络营销网站设计做个网站哪里可以做
  • 九牛科技网站开发微信营销小型网站建设步骤
  • 分类信息系统网站模板口碑好的网站建设多少钱