快速业务通道

linux的内核日志系统

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-04-15
= 0;

  console_may_schedule = 0;

  up(&console_sem);

  spin_unlock_irqrestore(&logbuf_lock, flags);

  if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) //如果内核唤醒缓冲中有数据,那么就唤醒睡眠队列 拥有帝国一切,皆有可能。欢迎访问phome.net

  wake_up_interruptible(&log_wait);

  }

  我们看一下procfs导出的kmsg接口的read函数,其实也是调用了do_syslog函数:

  static ssize_t kmsg_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)

  {

  if ((file->f_flags & O_NONBLOCK) && !do_syslog(9, NULL, 0))

  return -EAGAIN;

  return do_syslog(2, buf, count);

  }

  这里我觉得有一个问题,就是在printk的时候,如果我们恰好可以得到设备的信号量,那么就等到信息完全显示到设备上时调用栈才可以返回,也 就是说,最好不要在内核大量调用printk函数,另外,在多处理器上这也是很不利的,以前的处理器少,因此问题不大,现在都是多处理器了,性能就可能受 printk的影响了,我觉得可以为每一个cpu准备一个环形缓冲区,然后在拼接这些缓冲区的时候进行控制,比如在用户空间读每个cpu的缓冲区,只不过 将它们作为一个整体去理解,这个我感觉可以用文件系统实现.在任何程序中频繁调用打印都是不妙的,打印涉及设备操作,想想看,外设相比cpu多么慢, 对于机器中的唯一设备,是每个进程几乎都在用的设备,我们花在打架上的时间又是何等的长.

  回归同事问我的那个问题,在linux上怎么打印信息,其实,只要你不关闭,每个程序都会默认打开0,1,2三个文件描述符,这三个描述符在start_kernel中调用的kernel_init进程(最终成为/sbin/init)中被初始化,也就是在下面的代码:

  if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)

  printk(KERN_WARNING "Warning: unable to open an initial console. ");

  (void) sys_dup(0);

  (void) sys_dup(0);

  在这里,sys_open打开了/dev/console,将其作为标准输出,其实也就是我们的终端,当前终端,在sys_open中会自动将文件 描述符0分配给这个终端文件,然后紧接着的sys_dup相当于复制了这个终端文件描述符代表的文件给了新的描述符1和2,这样的话实际上0,1,2代表 的是同一个东西,都是指当前的终端,这也就是为什么你往标准错误里面写东西也不会错的道理,实际上标准输入,输出,错误都是给用户进程用的,对于内核,它 们是一个东西.linux进程都是fork出来的,根源就是这个kernel_init进程,于是每个进程都会默认复制父进程的0,1,2文件描述符 (如果父进程没有关闭它们的话). 拥有帝国一切,皆有可能。欢迎访问phome.net

拥有帝国一切,皆有可能。欢迎访问phome.net

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号