免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3891 | 回复: 6
打印 上一主题 下一主题

[函数] 系统函数或者语言实现的源码 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-04-04 17:20 |只看该作者 |倒序浏览
看CORBA讲到一个尖锐的问题,就是从I/O读入输入的字符(长度没有限制),然后返回给调用他的程序。里面列举了3种方法的对比。
其中一种讲到了UNIX 的系统read函数。
我一直想看看这些read,printf之类怎么实现的,当然windows下面反汇编可以看到汇编代码。但是我不知道比如read到底是怎么实现的?

后来我查到Linux内核中循环缓冲区(http://www.kerneltravel.net/jiaoliu/kern-kfifo.html),明白了点内核是怎么处理缓冲区的,但是缓冲区的大小还是不清楚怎么查到?
  1. unsigned int __kfifo_put(struct kfifo *fifo, unsigned char *buffer, unsigned int len)
  2. {
  3.      unsigned int l;
  4.      len = min(len, fifo->size - fifo->in + fifo->out);
  5. ...
  6.     smp_mb();

  7. /* first put the data starting from fifo->in to buffer end */
  8.     l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
  9.    memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);

  10. /* then put the rest (if any) at the beginning of the buffer */
  11.    memcpy(fifo->buffer, buffer + l, len - l);
  12. ...
  13. smp_wmb();

  14.    fifo->in += len;
  15.    return len;
  16. }
复制代码
还有比如我看到STL里面vector的find函数,在手册里面没有查到,就像去看他是怎么实现的,可是不知道怎么查找源码?

还有关于C语言或者C++语言的实现问题,我一直在想,但是想不明白:
c/c++语言的实现可否说是编译器实现的一部分,包括头文件里面函数的实现,和语法检查。

烦请高手们解答,谢谢。

论坛徽章:
0
2 [报告]
发表于 2010-04-04 17:26 |只看该作者
GNU LibC
GNU stdlibC++

论坛徽章:
0
3 [报告]
发表于 2010-04-04 20:28 |只看该作者
本帖最后由 crease2 于 2010-04-04 20:30 编辑

Linux下是怎么read?当年我也很疑惑,因为read最终会涉及到磁盘操作,肯定要用汇编的。
现在在看DUOS才知道,UNIX里面read,write还不是最底层的,下面还有一层buffer cache。
程序员眼中文件是连续的字节流,底层调用的眼中文件是连续的block流,inode里面文件又是由分散在磁盘各个地方的block组成。read代码的主体是个while循环,通过某些系统调用,进行上面所说的两层映射,找到程序员要读的字节在磁盘的block.一个block一个block地处理。
Linux的话还没有研究,看Lz找到的资料应该也是类似机制吧.read的代码可以在Linux的源文件里找到。
C++不太懂,STL应该相当于C语言里的标准库吧。C语言规范只是一纸空文,一个遵循规范的编译器,最终怎样解释代码的并不重要,只要满足规范中所要求的一切即可。规范中没有明确指出的地方,就由编译器的作者自行决定此处会发生什么现象。
规范中还有一个标准库,遵循规范的话一定要提供这些函数。函数的声明是怎么样的,会有什么行为,在规范中都有说明。所以只要满足规范中的要求,这些库函数怎么写都可以。故没有标准的库函数代码。gcc里的库函数与vc里的库函数代码的样子可能差很远,网上应该也有好受者自行实现的版本。LZ可以选一种现实研究一下。GNU的网站上有glibc的源代码,glibc就是gnu版的C标准库的实现。STL应该也差不多吧。

论坛徽章:
0
4 [报告]
发表于 2010-04-04 22:29 |只看该作者
本帖最后由 LaoLiulaoliu 于 2010-04-05 01:55 编辑

谢谢楼上,讲的我茅塞顿开,算是有一个理解上面的突破。
太感谢了!

问题继续中……

论坛徽章:
0
5 [报告]
发表于 2010-04-05 02:14 |只看该作者
我打开glibc,找到io/read.c 发现没有汇编,但是是很奇怪的C代码:
  1. #include <errno.h>
  2. #include <unistd.h>
  3. #include <stddef.h>

  4. /* Read NBYTES into BUF from FD.  Return the number read or -1.  */
  5. ssize_t
  6. __libc_read (int fd, void *buf, size_t nbytes)
  7. {
  8.   if (nbytes == 0)
  9.     return 0;
  10.   if (fd < 0)
  11.     {
  12.       __set_errno (EBADF);
  13.       return -1;
  14.     }
  15.   if (buf == NULL)
  16.     {
  17.       __set_errno (EINVAL);
  18.       return -1;
  19.     }

  20.   __set_errno (ENOSYS);
  21.   return -1;
  22. }
  23. libc_hidden_def (__libc_read)
  24. stub_warning (read)

  25. weak_alias (__libc_read, __read)
  26. libc_hidden_weak (__read)
  27. weak_alias (__libc_read, read)
  28. #include <stub-tag.h>
复制代码
比如libc_hidden_def(),stub_warning(),libc_hidden_weak(),weak_alias()有没有类似函数的介绍和用法。
我用sourceinsight看,发现有许多的定义,跳转到定义处,发现有更多的未知函数。求教如何来读这个read.c

论坛徽章:
0
6 [报告]
发表于 2010-04-05 11:50 |只看该作者
glibc

论坛徽章:
0
7 [报告]
发表于 2010-04-06 11:10 |只看该作者
没有那么复杂 其实很简单 写过 write 实现
  1. .section .data
  2. MSG:
  3.         .ascii  "hello world linux gas  \n "
  4. .section .bss

  5. .section .text
  6. .global _start

  7. _start:
  8.         xor %eax ,%eax
  9.         movl $4 ,%eax
  10.         movl $1 ,%ebx
  11.         movl $MSG , %ecx
  12.         movl $23 ,%edx
  13.         int  $0x80

  14. _exit:
  15.    movl $1 ,%eax
  16.    movl $0 ,%ebx
  17.    int  $0x80
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP