printk和printf的区别

2024-06-14 01:58
文章标签 区别 printk printf

本文主要是介绍printk和printf的区别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

内核使用printk()打印!
应用层使用printf()打印!

&&& 大部分常用的C库函数在Linux内核中都已经得到了实现。在所有没有实现的函数中,最著名的就数printf()函数了。内核代码虽然无法调用 printf()函数,但它可以调用printk()函数。printk()函数负责把格式化好的字符串拷贝到内核日志缓冲上,这样syslog程序就可 以通过读取该缓冲区来获取内核信息。printk()的用法很像printf(): 

printk("Hello world!A string:%s and an integer:%d\n",a_string,an_integer); 

printk()和printf()之间的一个显著区别在于printk()允许通过指定一个标志来设置优先级。syslog会根据这个优先级标 志来决定在什么地方显示这条系统信息。下面是一个使用这种优先级标志的例子: 

printk(KERN_ERR "this is an error!\n");

&&&&& printk()函数是直接使用了向终端写函数tty_write()。而printf()函数是调用write()系统调用函数向标准输出设备写。所以 在用户态(如进程0)不能够直接使用printk()函数,而在内核态由于他已是特权级,所以无需系统调用来改变特权级,因而能够直接使用 printk()函数。

printf是咋使用了标准的C库函数的时候才能使用的,而内核中无法使用标准的C库函数,所以就连最常见的printf都不能使用。

    例如子printk函数的字符串参数中使用了KERN_ALERT,它实际上扩展为字符串:“<1>”,而这部分信息没有输出到终端。实际上,这部分是内核信息的日志级别,只有超过了当前日志级别的信息才会输出到终端。当前内核的日志级别可以在/proc/sys/kernel/printk文件中看到。这个文件包含了四个整数,其中前两个是控制台的当前日志级别和默认日志级别。我们在printk的参数中使用较高的日志级别就是要保证信息得到输出。在<linux/kernel.h>头文件里一共定义了8个级别(0-7)的输出,从高到低分别由如下常量表示:

KERN_EMERG         :    最高级别,一般只用来打印崩溃信息

KERN_ALERT         :    需要立即处理的信息

KERN_CRIT          :    关键信息,一般用来显示严重的硬件和软件错误

KERN_ERR           :    用来显示硬件错误

KERN_WARNING       :    显示不会造成严重错误的警告信息

KERN_NOTICE        :    显示需要引起注意的信息

KERN_INFO          :  显示一般信息,例如驱动所发现的硬件列表

KERN_DEBUG    :  用来显示调试信息

 

    printk与printf的一个区别printk是“行驱动”的,也就是说只有收到一个换行符数据才会真正输出到终端,否则就不会有任何信息输出。另一个值得注意的问题是我们在调试嵌入式设备的时候,经常是从串口获得显示信息,如果我们使用printk过于频繁的话,串口的传输速度就会成为瓶颈,这样会造成系统的性能下降甚至停止反应。    

这篇关于printk和printf的区别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1059056

相关文章

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对

Redis中哨兵机制和集群的区别及说明

《Redis中哨兵机制和集群的区别及说明》Redis哨兵通过主从复制实现高可用,适用于中小规模数据;集群采用分布式分片,支持动态扩展,适合大规模数据,哨兵管理简单但扩展性弱,集群性能更强但架构复杂,根... 目录一、架构设计与节点角色1. 哨兵机制(Sentinel)2. 集群(Cluster)二、数据分片

一文带你迅速搞懂路由器/交换机/光猫三者概念区别

《一文带你迅速搞懂路由器/交换机/光猫三者概念区别》讨论网络设备时,常提及路由器、交换机及光猫等词汇,日常生活、工作中,这些设备至关重要,居家上网、企业内部沟通乃至互联网冲浪皆无法脱离其影响力,本文将... 当谈论网络设备时,我们常常会听到路由器、交换机和光猫这几个名词。它们是构建现代网络基础设施的关键组成

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

JAVA覆盖和重写的区别及说明

《JAVA覆盖和重写的区别及说明》非静态方法的覆盖即重写,具有多态性;静态方法无法被覆盖,但可被重写(仅通过类名调用),二者区别在于绑定时机与引用类型关联性... 目录Java覆盖和重写的区别经常听到两种话认真读完上面两份代码JAVA覆盖和重写的区别经常听到两种话1.覆盖=重写。2.静态方法可andro

C++中全局变量和局部变量的区别

《C++中全局变量和局部变量的区别》本文主要介绍了C++中全局变量和局部变量的区别,全局变量和局部变量在作用域和生命周期上有显著的区别,下面就来介绍一下,感兴趣的可以了解一下... 目录一、全局变量定义生命周期存储位置代码示例输出二、局部变量定义生命周期存储位置代码示例输出三、全局变量和局部变量的区别作用域

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Javaee多线程之进程和线程之间的区别和联系(最新整理)

《Javaee多线程之进程和线程之间的区别和联系(最新整理)》进程是资源分配单位,线程是调度执行单位,共享资源更高效,创建线程五种方式:继承Thread、Runnable接口、匿名类、lambda,r... 目录进程和线程进程线程进程和线程的区别创建线程的五种写法继承Thread,重写run实现Runnab