一些常用的函数 宏
来源:互联网 发布:包车软件哪个好 编辑:程序博客网 时间:2024/05/21 11:12
<!--@page { margin: 2cm }P { margin-bottom: 0cm }P.western { font-size: 10pt }P.cjk { font-size: 10pt }H1 { margin-bottom: 0.21cm }H1.western { font-family: "Arial", sans-serif; font-size: 16pt }H1.cjk { font-family: "文鼎PL简中楷"; font-size: 16pt }H1.ctl { font-family: "文鼎PL简中楷"; font-size: 16pt }-->
内核相关:kthread_create、kthread_run、kthread_stop、Asmlinkage、HZtick and jiffie、BUG()、BUG_ON()、shmat
c相关:<!--@page { margin: 2cm }P { margin-bottom: 0cm }P.western { font-size: 10pt }P.cjk { font-size: 10pt }H1 { margin-bottom: 0.21cm }H1.western { font-family: "Arial", sans-serif; font-size: 16pt }H1.cjk { font-family: "文鼎PL简中楷"; font-size: 16pt }H1.ctl { font-family: "文鼎PL简中楷"; font-size: 16pt }TD P { margin-bottom: 0cm }A:link { so-language: zxx }--> memchr、strncmp、sscanf、Sprintf、isspace
<!--@page { margin: 2cm }P { margin-bottom: 0cm }P.western { font-size: 10pt }P.cjk { font-size: 10pt }H1 { margin-bottom: 0.21cm }H1.western { font-family: "Arial", sans-serif; font-size: 16pt }H1.cjk { font-family: "文鼎PL简中楷"; font-size: 16pt }H1.ctl { font-family: "文鼎PL简中楷"; font-size: 16pt }-->
kthread_create
使用kthread_create创建线程:
structtask_struct *kthread_create(int (*threadfn)(void *data),
void*data,
const char *namefmt, ...);
这个函数可以像printk一样传入某种格式的线程名
线程创建后,不会马上运行,而是需要将kthread_create()返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。
kthread_run
当然,还有一个创建并启动线程的函数:kthread_run
struct task_struct *kthread_run(int (*threadfn)(void *data),
void*data,
const char *namefmt, ...);
kthread_stop
线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。
int kthread_stop(structtask_struct *thread);
kthread_stop() 通过发送信号给线程。
如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远不返回并且不检查信号,它将永远都不会停止。
在执行kthread_stop的时候,目标线程必须没有退出,否则会Oops。原因很容易理解,当目标线程退出的时候,其对应的task结构也变得无效,kthread_stop引用该无效task结构就会出错。
Asmlinkage
看一下/usr/include/asm/linkage.h里面的定义:
#defineasmlinkage CPP_ASMLINKAGE__attribute__((regparm(0)))
__attribute__是关键字,是gcc的C语言扩展,regparm(0)表示不从寄存器传递参数
如果是__attribute__((regparm(3))),那么调用函数的时候参数不是通过栈传递,而是直接放到寄存器里,被调用函数直接从寄存器取参数。
如:asmlinkagelong sys_sync(void);
HZ, tick and jiffie
linux核心每隔固定遧期會發出timerinterrupt (irq 0),hz是用來定義每一秒有幾次timerinterrupts。
tick是hz的倒數,意即timerinterrupt每發生一次中斷的時間。如hz為250時,tick為4毫秒(millisecond)。
jiffies為linux核心變數(unsignedlong),它被用來紀錄系統自開幾以來,已經過多少的tick。
BUG()、BUG_ON()
作用:一些内核调用可以用来方便标记bug,提供断言并输出信息。最常用的两个是BUG()和BUG_ON()。当被调用的时候,它们会引发oops,导致栈的回溯和错误信息的打印。为什么这些声明会导致oops跟硬件的体系结构是相关的。大部分体系结构把BUG()和BUG_ON()定义成某种非法操作,这样自然会产生需要的oops。你可以把这些调用当作断言使用,想要断言某种情况不该发生:
if(bad_thing)
BUG();
或者使用更好的形式:
BUG_ON(bad_thing);
可以用panic()引发更严重的错误。调用panic()不但会打印错误消息而且还会挂起整个系统。显然,你只应该在极端恶劣的情况下使用它:
if(terrible_thing)
panic("foo is %ld/n", foo);
有些时候,你只是需要在终端上打印一下栈的回溯信息来帮助你测试。此时可以使用dump_stack()。它只在终端上打印寄存器上下文和函数的跟踪线索:
if(!debug_check) {
printk(KERN_DEBUG "provide someinformation.../n");
dump_stack();
}
from:http://www.lupaworld.com/bbs/thread-36983-1-8.html
Alots of places in linux kernel we encounter the macro BUG_ON.
BUG_ONmacro first checks for the condition and if condition is true then itcalls BUG which do a printk of msg and call panic which halts thesystem.(如果BUG_ON中的条件为真就调用BUG,它输出一些信息,然后调用panic函数挂起系统。)
Theunlikely in BUG_ON macro is compiler directive whichask compiler to generate assembly such that the condition mentionedin unlikely isn't going to be met most-of-the time , which reducesjumps and speeds-up things, although if condition mentioned inunlikely met then there will be a long jump and speed will beeffected, so must be used carefully. Same is with likely as it is theopposite of unlikely .(据说likely一般是很少用的)
shmat
作用:共享内存区对象映射到调用进程的地址空间
核心处理函数:void*shmat( int shmid , char *shmaddr , int shmflag);shmat()是用来允许本进程访问一块共享内存的函数。
intshmid是那块共享内存的ID。
char*shmaddr是共享内存的起始地址
intshmflag是本进程对该内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。其它的是读写模式
成功时,这个函数返回共享内存的起始地址。失败时返回-1
最近用到内存共享,收集整理了些资料,做了个简单的对比
memchr
原型:externvoid *memchr(void *buf, char ch, unsigned count);
头文件:#include<string.h>
功能:从buf所指内存区域的前count个字节查找字符ch。
说明:当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回NULL。
strncmp
原型:externint strcmp(char *s1,char * s2,intn);
头文件:#include<string.h>
功能:比较字符串s1和s2的前n个字符。
说明:
当s1<s2时,返回值<0
当s1=s2时,返回值=0
当s1>s2时,返回值>0
sscanf
函数原型:
Int sscanf(const char *, const char *, ...);
int scanf(const char *, ...);
头文件:#include<stdio.h>
1.常见用法。
charbuf[512] = ;
sscanf("123456", "%s", buf);//此处buf是数组名,它的意思是将123465以%s的形式存入buf中!
返回值:有多少个变量被赋值。intn= sscanf(str,"%2d%2d",&x,&y);
Sprintf
函数原型:
#include<stdio.h>
intsprintf(char *string, char *farmat [,argument,...]);
详细描述:函数sprintf()的用法和printf()函数一样,只是sprintf的作用是将一个格式化的字符串输出到一个目的字符串中,而printf是将一个格式化的字符串输出到屏幕。
例如: sprintf(s,"%d", 123); //把整数123打印成一个字符串保存在s中。
返回值:返回本次函数调用打印到字符缓冲区中的字符数目
isspace
#include<ctype.h>
定义函数
intisspace(int c)
函数说明:检查参数c是否为空格字符,也就是判断是否为空格('')、定位字符('/t')、CR('/r')、换行('/n')、垂直定位字符('/v')或翻页('/f')的情况。
返回值 :若参数c为空格字符,则返回TRUE,否则返回NULL(0)。
附加说明: 此为宏定义,非真正函数。
基本C库函数
当编写驱动程序时,一般情况下不能使用C标准库的函数。Linux内核也提供了与标准库函数功能相同的一些函数,但二者还是稍有差别。
类别
函数名
功能
函数形成
参数
描述
字符串转换
simple_strtol
把一个字符串转换为一个有符号长整数
longsimple_strtol (const char * cp, char ** endp, unsigned int base)
cp指向字符串的开始,endp为指向要分析的字符串末尾处的位置,base为要用的基数。
simple_strtoll
把一个字符串转换为一个有符号长长整数
long longsimple_strtoll (const char * cp, char ** endp, unsigned int base)
cp指向字符串的开始,endp为指向要分析的字符串末尾处的位置,base为要用的基数。
simple_strtoul
把一个字符串转换为一个无符号长整数
long longsimple_strtoul (const char * cp, char ** endp, unsigned int base)
cp指向字符串的开始,endp为指向要分析的字符串末尾处的位置,base为要用的基数。
simple_strtoull
把一个字符串转换为一个无符号长长整数
long longsimple_strtoull (const char * cp, char ** endp, unsigned int base)
cp指向字符串的开始,endp为指向要分析的字符串末尾处的位置,base为要用的基数。
vsnprintf
格式化一个字符串,并把它放在缓存中。
intvsnprintf (char * buf, size_t size, const char * fmt, va_listargs)
buf为存放结果的缓冲区,size为缓冲区的大小,fmt为要使用的格式化字符串,args为格式化字符串的参数。
snprintf
格式化一个字符串,并把它放在缓存中。
intsnprintf (char * buf, size_t size, const char * fmt, ... ...)
buf为存放结果的缓冲区,size为缓冲区的大小,fmt为格式化字符串,使用@…来对格式化字符串进行格式化,…为可变参数。
vsprintf
格式化一个字符串,并把它放在缓存中。
intvsprintf (char * buf, const char * fmt, va_list args)
buf为存放结果的缓冲区,size为缓冲区的大小,fmt为要使用的格式化字符串,args为格式化字符串的参数。
sprintf
格式化一个字符串,并把它放在缓存中。
int sprintf(char * buf, const char * fmt, ... ...)
buf为存放结果的缓冲区,size为缓冲区的大小,fmt为格式化字符串,使用@…来对格式化字符串进行格式化,…为可变参数。
字符串操作
strcpy
拷贝一个以NUL结束的字符串
char *strcpy (char * dest, const char * src)
dest为目的字符串的位置,src为源字符串的位置。
strncpy
拷贝一个定长的、以NUL结束的字符串
char *strncpy (char * dest, const char * src, size_t count)
dest为目的字符串的位置,src为源字符串的位置,count为要拷贝的最大字节数
与用户空间的strncpy不同,这个函数并不用NUL填充缓冲区,如果与源串超过count,则结果以非NUL结束
strcat
把一个以NUL结束的字符串添加到另一个串的末尾
char *strcat (char * dest, const char * src)
dest为要添加的字符串,src为源字符串。
strncat
把一个定长的、以NUL结束的字符串添加到另一个串的末尾
char *strncat (char * dest, const char * src, size_t count)
dest为要添加的字符串,src为源字符串,count为要拷贝的最大字节数
注意,与strncpy,形成对照,strncat正常结束。
strchr
在一个字符串中查找第一次出现的某个字 符
char *strchr (const char * s, int c)
s为被搜索的字符串,c为待搜索的字符。
strrchr
在一个字符串中查找最后一次出现的某个 字符
char *strrchr (const char * s, int c)
s为被搜索的字符串,c为待搜索的字符。
strlen
给出一个字符串的长度
size_tstrlen (const char * s)
s为给定的字符串
strnlen
给出给定长度字符串的长度
size_tstrnlen (const char * s, size_t count)
s为给定的字符串
strpbrk
在一个字符串中查找第一次出现的一组字 符
char *strpbrk (const char * cs, const char * ct)
cs为被搜索的字符串,ct为待搜索的一组字符
strtok
把一个字符串分割为子串
char *strtok (char * s, const char * ct)
s为被搜索的字符串,ct为待搜索的子串
注意,一般不提倡用这个函数,而应当用strsep
memset
用给定的值填充内存区
void *memset (void * s, int c, size_t count)
s为指向内存区起始的指针,c为要填充的内 容,count为内存区的大小
I/O空间的访问不能使用memset,而应当使用memset_io。
bcopy
把内存的一个区域拷贝到另一个区域
char *bcopy (const char * src, char * dest, int count)
src为源字符串,dest为目的字符串,而count为内存区的大小
注意,这个函数的功能与memcpy相同,这是从BSD遗留下来的,对I/O空间的访问应当用memcpy_toio或memcpy_fromio
memcpy
把内存的一个区域拷贝到另一个区域
void *memcpy (void * dest, const void * src, size_t count)
dest为目的字符串,Src为源字符串,而count为内存区的大小
对I/O空间的访问应当用memcpy_toio或memcpy_fromio
memmove
把内存的一个区域拷贝到另一个区域
void *memmove (void * dest, const void * src, size_t count)
dest为目的字符串,Src为源字符串,而count为内存区的大小
memcpy和memmove处理重叠的区域,而该函数不处理。
memcmp
比较内存的两个区域
int memcmp(const void * cs, const void * ct, size_t count)
cs为一个内存区,ct为另一个内存区,而count为内存区的大小
memscan
在一个内存区中查找一个字符
void *memscan (void * addr, int c, size_t size)
addr为内存区,c为要搜索的字符,而size为内存区的大小
返回c第一次出现的地址,如果没有找到c,则向该内存区传递一个字节。
strstr
在以NUL结束的串中查找第一个出现的子串
char *strstr (const char * s1, const char * s2)
s1为被搜索的串,s2为待搜索的串。
memchr
在一个内存区中查找一个字符
void *memchr (const void * s, int c, size_t n)
s为内存区,为待搜索的字符,n为内存的大小
返回c第一次出现的位置,如果没有找到c,则返回空。
位操作
set_bit
在位图中原子地设置某一位
voidset_bit (int nr, volatile void * addr)
nr为要设置的位,addr为位图的起始地址
这个函数是原子操作,如果不需要原子操作,则调用__set_bit函数,nr可以任意大,位图的大小不限于一个字。
__set_bit
在位图中设置某一位
void__set_bit (int nr, volatile void * addr)
nr为要设置的位,addr为位图的起始地址
clear_bit
在位图中清某一位
voidclear_bit (int nr, volatile void * addr)
nr为要清的位,addr为位图的起始地址
该函数是原子操作,但不具有加锁功能,如果要用于加锁目的,应当调用smp_mb__before_clear_bit或smp_mb__after_clear_bit函数,以确保任何改变在其他的处理器上是可见的。
__change_bit
在位图中改变某一位
void__change_bit (int nr, volatile void * addr)
nr为要设置的位,addr为位图的起始地址。
与change_bit不同,该函数是非原子操作。
change_bit
在位图中改变某一位
voidchange_bit (int nr, volatile void * addr)
nr为要设置的位,addr为位图的起始地址。
test_and_set_bit
设置某一位并返回该位原来的值
inttest_and_set_bit (int nr, volatile void * addr)
nr为要设置的位,addr为位图的起始地址。
该函数是原子操作
__test_and_set_bit
设置某一位并返回该位原来的值
int__test_and_set_bit (int nr, volatile void * addr)
nr为要设置的位,addr为位图的起始地址。
该函数是非原子操作,如果这个操作的两个实例发生竞争,则一个成功而另一个失败,因此应当用一个锁来保护对某一位的多个访问。
test_and_clear_bit
清某一位,并返回原来的值
inttest_and_clear_bit (int nr, volatile void * addr);
nr为要设置的位,addr为位图的起始地址。
该函数是原子操作
__test_and_clear_bit
清某一位,并返回原来的值
int__test_and_clear_bit (int nr, volatile void * addr);
nr为要设置的位,addr为位图的起始地址。
该函数为非原子操作
test_and_change_bit
改变某一位并返回该位的新值
inttest_and_change_bit (int nr, volatile void * addr)
nr为要设置的位,addr为位图的起始地址。
该函数为原子操作
test_bit
确定某位是否被设置
inttest_bit (int nr, const volatile void * addr)
nr为要测试的第几位,addr为位图的起始地址。
find_first_zero_bit
在内存区中查找第一个值为0的位
intfind_first_zero_bit (void * addr, unsigned size)
addr为内存区的起始地址,size为要查找的最大长度
返回第一个位为0的位号
find_next_zero_bit
在内存区中查找第一个值为0的位
intfind_next_zero_bit (void * addr, int size, int offset)
addr为内存区的起始地址,size为要查找的最大长度,offset开始搜索的起始位号。
ffz
在字中查找第一个0
unsignedlong ffz (unsigned long word);
word为要搜索的字。
ffs
查找第一个已设置的位
int ffs(int x)
x为要搜索的字。
这个函数的定义方式与Libc中的一样。
hweight32
返回一个N位字的加权平衡值
hweight32 (x)
x为要加权的字
一个数的加权平衡是这个数所有位的总和。
kthread_create
使用kthread_create创建线程:
structtask_struct *kthread_create(int (*threadfn)(void *data),
void*data,
const char *namefmt, ...);
这个函数可以像printk一样传入某种格式的线程名
线程创建后,不会马上运行,而是需要将kthread_create()返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。
kthread_run
当然,还有一个创建并启动线程的函数:kthread_run
struct task_struct *kthread_run(int (*threadfn)(void *data),
void*data,
const char *namefmt, ...);
kthread_stop
线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。
int kthread_stop(structtask_struct *thread);
kthread_stop() 通过发送信号给线程。
如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远不返回并且不检查信号,它将永远都不会停止。
在执行kthread_stop的时候,目标线程必须没有退出,否则会Oops。原因很容易理解,当目标线程退出的时候,其对应的task结构也变得无效,kthread_stop引用该无效task结构就会出错。
Asmlinkage
看一下/usr/include/asm/linkage.h里面的定义:
#defineasmlinkage CPP_ASMLINKAGE__attribute__((regparm(0)))
__attribute__是关键字,是gcc的C语言扩展,regparm(0)表示不从寄存器传递参数
如果是__attribute__((regparm(3))),那么调用函数的时候参数不是通过栈传递,而是直接放到寄存器里,被调用函数直接从寄存器取参数。
如:asmlinkagelong sys_sync(void);
HZ, tick and jiffie
linux核心每隔固定遧期會發出timerinterrupt (irq 0),hz是用來定義每一秒有幾次timerinterrupts。
tick是hz的倒數,意即timerinterrupt每發生一次中斷的時間。如hz為250時,tick為4毫秒(millisecond)。
jiffies為linux核心變數(unsignedlong),它被用來紀錄系統自開幾以來,已經過多少的tick。
BUG()、BUG_ON()
作用:一些内核调用可以用来方便标记bug,提供断言并输出信息。最常用的两个是BUG()和BUG_ON()。当被调用的时候,它们会引发oops,导致栈的回溯和错误信息的打印。为什么这些声明会导致oops跟硬件的体系结构是相关的。大部分体系结构把BUG()和BUG_ON()定义成某种非法操作,这样自然会产生需要的oops。你可以把这些调用当作断言使用,想要断言某种情况不该发生:
if(bad_thing)
BUG();
或者使用更好的形式:
BUG_ON(bad_thing);
可以用panic()引发更严重的错误。调用panic()不但会打印错误消息而且还会挂起整个系统。显然,你只应该在极端恶劣的情况下使用它:
if(terrible_thing)
panic("foo is %ld/n", foo);
有些时候,你只是需要在终端上打印一下栈的回溯信息来帮助你测试。此时可以使用dump_stack()。它只在终端上打印寄存器上下文和函数的跟踪线索:
if(!debug_check) {
printk(KERN_DEBUG "provide someinformation.../n");
dump_stack();
}
from:http://www.lupaworld.com/bbs/thread-36983-1-8.html
Alots of places in linux kernel we encounter the macro BUG_ON.
BUG_ONmacro first checks for the condition and if condition is true then itcalls BUG which do a printk of msg and call panic which halts thesystem.(如果BUG_ON中的条件为真就调用BUG,它输出一些信息,然后调用panic函数挂起系统。)
Theunlikely in BUG_ON macro is compiler directive whichask compiler to generate assembly such that the condition mentionedin unlikely isn't going to be met most-of-the time , which reducesjumps and speeds-up things, although if condition mentioned inunlikely met then there will be a long jump and speed will beeffected, so must be used carefully. Same is with likely as it is theopposite of unlikely .(据说likely一般是很少用的)
shmat
作用:共享内存区对象映射到调用进程的地址空间
核心处理函数:void*shmat( int shmid , char *shmaddr , int shmflag);shmat()是用来允许本进程访问一块共享内存的函数。
intshmid是那块共享内存的ID。
char*shmaddr是共享内存的起始地址
intshmflag是本进程对该内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。其它的是读写模式
成功时,这个函数返回共享内存的起始地址。失败时返回-1
最近用到内存共享,收集整理了些资料,做了个简单的对比
- 一些常用的函数 宏
- 一些常用的函数
- 一些常用的函数
- 一些常用的函数
- ASP的一些常用函数!
- 一些常用的Asp函数
- 一些常用的Delphi函数
- 常用的一些处理函数
- 常用的一些处理函数
- 常用的一些处理函数
- 一些常用的php函数
- 一些个人常用的函数
- 一些常用的JS函数
- 一些常用的JS函数
- 常用的一些函数WaitForSingleObject
- 一些常用的基本函数
- 一些SQL的常用函数
- 一些个人常用的函数
- Linux下SVN+Apache简要安装记录
- perl学习笔记三----操作符
- Xbox360通过无线连接到路由器上vpn的教程
- C++ VS C#(6):入口函数,改变形参数值
- perl学习笔记四----流程控制
- 一些常用的函数 宏
- perl学习笔记六----函数
- 关于EditorGridPanel移位的问题
- perl学习笔记七----文件
- gcc cmake 编译选项汇总
- Asp.Net中String.Empty、null和""的区别
- 关于调用不到方法的问题
- perl学习笔记八----格式化输出
- 《Google App Engine编程:英文版》