学习LINUX下C编程前提是要懂得LINUX。当然除了懂LINUX之外,还要了解一个程序是怎么样在操作系统之上进行运行的。这就需要了解LINUX向上提供了什么。所有这些就是我们通常意义上的SHELL,系统调用API等等,因此基于LINUX的开发程序需要了解这些系统CALL和SHELL。当然这些预定义的SHELL和CALL都非常多,怎么查看呢?两个地方,一个网站,一个手册。这个手册就类似于WINDOWSHELP一样,可以实时查看。使用命令man
【1】 man 是用来格式化显示在线手册的命令。大部分LINUX缺省的软件都带有MAN文档,GNU的工具安装后也会带有MAN文档,这些文档安装在/usr/share/man下
[root@windriver-machine shtest]# ls /usr/share/man/
bg da el eo fi fr.ISO8859-1 hr id it.ISO8859-1 ja man0p man1p man2 man3 man3x man4x man5x man6x man7x man8x man9x nl pl.ISO8859-2 pt ro ru.KOI8-R sk sv zh_CN cs de en es fr fr.UTF-8 hu it it.UTF-8 ko man1 man1x man2x man3p man4 man5 man6 man7 man8 man9 mann pl pl.UTF-8 pt_BR ru ru.UTF-8 sl tr zh_TW [root@windriver-machine shtest]#man是区分章节的,这个章节的内容就是查看的对象它可能是一个SHELL命令,也可能是一个系统函数,还有可能一些其它的东西。LINUX MAN将之分成8类,每个章节打成一个gz 包,分别存放在man1,man2…这些不同的目录下。缺省的类别如下:
可以使用man 1 fork 或者man 2 kill之类方式查看。自己也可以制作相应的文档文件,打包压缩成section.gz放到指定的目录如/usr/share/man/man1下,也可以使用-M指定特定目录。
[root@windriver-machine shtest]# ls /usr/share/man/man1/ |more
:.1.gz [.1.gz 411toppm.1.gz a2p.1.gz a2ps.1.gz ab.1.gz ac.1.gz[root@windriver-machine shtest]# man -a fork
[root@windriver-machine shtest]# man -aw fork /usr/share/man/man2/fork.2.gz /usr/share/man/man3p/fork.3p.gz [root@windriver-machine shtest]# man 3 fork No entry for fork in section 3 of the manual [root@windriver-machine shtest]# man 2 fork [root@windriver-machine shtest]# man -w fork /usr/share/man/man2/fork.2.gz [root@windriver-machine shtest]# LANG=zh [root@windriver-machine shtest]# man -w fork /usr/share/man/man2/fork.2.gz [root@windriver-machine shtest]# LANG=de [root@windriver-machine shtest]# man -w fork /usr/share/man/man2/fork.2.gz [root@windriver-machine shtest]# LANG=zh_CN [root@windriver-machine shtest]# man -w kill /usr/share/man/man1/kill.1.gz [root@windriver-machine shtest]# ls -latr /usr/share/man/zh_CN/man man1/ man8/ [root@windriver-machine shtest]# ls -latr /usr/share/man/zh_CN/man1/ dcraw.1.gz newgrp.1.gz [root@windriver-machine shtest]# ls -latr /usr/share/man/zh_CN/man1/ \ufffd\u073c\ufffd 32 -rw-r--r-- 1 root root 3304 2007-02-05 dcraw.1.gz -rw-r--r-- 1 root root 772 2007-04-10 newgrp.1.gz drwxr-xr-x 4 root root 4096 05-18 00:13 .. drwxr-xr-x 2 root root 4096 05-18 00:13 . [root@windriver-machine shtest]# man dcraw [root@windriver-machine shtest]# man -w dcraw /usr/share/man/zh_CN/man1/dcraw.1.gz [root@windriver-machine shtest]# man -w newgrp /usr/share/man/zh_CN/man1/newgrp.1.gz [root@windriver-machine shtest]# man -f time Time::HiRes (3pm) - High resolution alarm, sleep, gettimeofday, interval timers Time::Local (3pm) - efficiently compute time from local and GMT time Time::gmtime (3pm) - by-name interface to Perl's built-in gmtime() function Time::localtime (3pm) - by-name interface to Perl's built-in localtime() function Time::tm (3pm) - internal object used by Time::gmtime and Time::localtime time (1) - time a simple command or give resource usage time (1p) - time a simple command time (2) - get time in seconds time (3p) - get time time (7) - overview of time time (rpm) - A GNU utility for monitoring a program's use of system resources time.conf [time] (5) - configuration file for the pam_time module time.h [time] (0p) - time types [root@windriver-machine shtest]#【2】在线man手册,有几个网站比较好
【3】libc库,在不同的LINUNX发布版本中通常有两种包,一种是以libc6-dev打头的,另一种是glibc-2打头的包,这两种其实都是一样的,只是在不同版本的LINUX/UNIX中叫法不一样,前者主要是Debian/ubuntu,后者redhat。但他们都是GNU发布的libc库。安装后显示如下:
[root@windriver-machine shtest]# rpm -qa|grep libc
glibc-2.6-3 libcdio-0.77-3.fc6 libcroco-devel-0.6.1-2.1 libchewing-0.3.0-6.fc7 glibc-devel-2.6-3 libcroco-0.6.1-2.1 glibc-headers-2.6-3 glibc-common-2.6-3 libcap-1.10-29 libcap-devel-1.10-29[root@windriver-machine shtest]# ls -latr /usr/include/glib-2.0/glib/g
galloca.h gbase64.h gdataset.h ghash.h gkeyfile.h gmarkup.h gpattern.h gqueue.h gslice.h gstring.h gtypes.h garray.h gbookmarkfile.h gdate.h ghook.h glist.h gmem.h gprimes.h grand.h gslist.h gthread.h gunicode.h gasyncqueue.h gcache.h gdir.h gi18n.h gmacros.h gmessages.h gprintf.h grel.h gspawn.h gthreadpool.h gutils.h gatomic.h gcompletion.h gerror.h gi18n-lib.h gmain.h gnode.h gqsort.h gscanner.h gstdio.h gtimer.h gwin32.h gbacktrace.h gconvert.h gfileutils.h giochannel.h gmappedfile.h goption.h gquark.h gshell.h gstrfuncs.h gtree.h [root@windriver-machine shtest]# ls -latr /usr/include/glib-2.0/glib/g galloca.h gbase64.h gdataset.h ghash.h gkeyfile.h gmarkup.h gpattern.h gqueue.h gslice.h gstring.h gtypes.h garray.h gbookmarkfile.h gdate.h ghook.h glist.h gmem.h gprimes.h grand.h gslist.h gthread.h gunicode.h gasyncqueue.h gcache.h gdir.h gi18n.h gmacros.h gmessages.h gprintf.h grel.h gspawn.h gthreadpool.h gutils.h gatomic.h gcompletion.h gerror.h gi18n-lib.h gmain.h gnode.h gqsort.h gscanner.h gstdio.h gtimer.h gwin32.h gbacktrace.h gconvert.h gfileutils.h giochannel.h gmappedfile.h goption.h gquark.h gshell.h gstrfuncs.h gtree.h [root@windriver-machine shtest]# ls -latr /usr/include/glib-2.0/glib/g【4】ulimit 是一种LINUX内部参数集,用于为由它生成的SHELL进程及其子进程的资源使用设置限制。这些限制包括所创建的内核文件的大小、进程数据块的大小、进程创建文件的大小、内存锁住的大小、常驻内存集的大小、文件描述符的数量、分配堆栈的最大大小、CPU时间、单个用户的最大线程数、使用的最大虚拟内存等。
[windriver@windriver-machine ~]$ ulimit -a
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 32742 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 32742 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [windriver@windriver-machine ~]$ulimit 是资源使用限制的一种,它主要是限制当前SHELL进程及其派生的子进程,也就是说,对同一个用户来说,如果同时运行了两个SHELL,在其中一个SHELL中使用ULIMIT命令是不会影响另一个SHELL的。如果针对用户进行限制,可以修改配置文件/etc/security/limit.conf
[windriver@windriver-machine ~]$ cat /etc/security/limits.conf
# /etc/security/limits.conf # #Each line describes a limit for a user in the form: # #<domain> <type> <item> <value> # #Where: #<domain> can be: # - an user name # - a group name, with @group syntax # - the wildcard *, for default entry # - the wildcard %, can be also used with %group syntax, # for maxlogin limit # #<type> can have the two values: # - "soft" for enforcing the soft limits # - "hard" for enforcing hard limits # #<item> can be one of the following: # - core - limits the core file size (KB) # - data - max data size (KB) # - fsize - maximum filesize (KB) # - memlock - max locked-in-memory address space (KB) # - nofile - max number of open files # - rss - max resident set size (KB) # - stack - max stack size (KB) # - cpu - max CPU time (MIN) # - nproc - max number of processes # - as - address space limit # - maxlogins - max number of logins for this user # - maxsyslogins - max number of logins on the system # - priority - the priority to run user process with # - locks - max number of file locks the user can hold # - sigpending - max number of pending signals # - msgqueue - max memory used by POSIX message queues (bytes) # - nice - max nice priority allowed to raise to # - rtprio - max realtime priority # #<domain> <type> <item> <value> ##* soft core 0
#* hard rss 10000 #@student hard nproc 20 #@faculty soft nproc 20 #@faculty hard nproc 50 #ftp hard nproc 0 #@student - maxlogins 4# End of file
[windriver@windriver-machine ~]$如使用* hard nofile 100 限制任意用户最大创建文件数量是100。针对进程和针对用户只是在不同级别的资源限制,如果要求全局限制,这时就需要修改/proc下的配置参数如/proc/sys/net/ipv4/ip_local_port_range修改IP端口范围。
ulimit 一个特性就是你第一次设了一个值之后重设的值只能比这个值小。除非你使用超级权限。这句话其实也不对,如果你使用了其它权限,其实设置是不同用户。因此,ulimit设置之后只能小。不能大。除非新建SHELL
[windriver@windriver-machine ~]$ ulimit -m 5000
[windriver@windriver-machine ~]$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 32742 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) 5000 open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 32742 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [windriver@windriver-machine ~]$ ulimit -m 4900 [windriver@windriver-machine ~]$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 32742 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) 4900 open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 32742 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [windriver@windriver-machine ~]$ ulimit -m 4950 bash: ulimit: max memory size: cannot modify limit: Operation not permitted [windriver@windriver-machine ~]$ man ulimit [windriver@windriver-machine ~]$ su - root Password: [root@windriver-machine ~]# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 32742 max locked memory (kbytes, -l) 32 max memory size (kbytes, -m) 4900 open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 32742 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited [root@windriver-machine ~]# ulimit -m unlimited [root@windriver-machine ~]#ulimit可以使用程序函数进行设置,两个函数setrlimit(), getrlimit()在glibc中。
【5】gcov工具 这个工具主要用来进行代码执行的覆盖测试,类似于JAVA中的emma,通过分析GCOV的结果来判断代码的健壮性。使用gcov 配合lcov生成HTML。gcov先用带参数-fprofile-arcs –ftest-coverage的gcc编译,当执行程序后会生成.c.gcov文件,使用gcov命令可以查看这些覆盖结果。
[windriver@windriver-machine ltest]$ gcc -fprofile-arcs -ftest-coverage gcov_exp.c -o gcov_exp
[windriver@windriver-machine ltest]$ ll gcov_exp* -rwxrwxr-x 1 windriver windriver 15274 2011-08-30 22:06 gcov_exp -rw-rw-r-- 1 windriver windriver 198 2011-08-30 22:05 gcov_exp.c -rw-rw-r-- 1 windriver windriver 572 2011-08-30 22:06 gcov_exp.gcno [windriver@windriver-machine ltest]$ ./gcov_exp Success [windriver@windriver-machine ltest]$ ll gcov_exp* -rwxrwxr-x 1 windriver windriver 15274 2011-08-30 22:06 gcov_exp -rw-rw-r-- 1 windriver windriver 198 2011-08-30 22:05 gcov_exp.c -rw-rw-r-- 1 windriver windriver 168 2011-08-30 22:08 gcov_exp.gcda -rw-rw-r-- 1 windriver windriver 572 2011-08-30 22:06 gcov_exp.gcno [windriver@windriver-machine ltest]$ gcov gcov_exp.c File 'gcov_exp.c' Lines executed:87.50% of 8 gcov_exp.c:creating 'gcov_exp.c.gcov'[windriver@windriver-machine ltest]$ gcov -a gcov_exp.c
File 'gcov_exp.c' Lines executed:87.50% of 8 gcov_exp.c:creating 'gcov_exp.c.gcov'[windriver@windriver-machine ltest]$ ll gcov_exp*
-rwxrwxr-x 1 windriver windriver 15274 2011-08-30 22:06 gcov_exp -rw-rw-r-- 1 windriver windriver 198 2011-08-30 22:05 gcov_exp.c -rw-rw-r-- 1 windriver windriver 832 2011-08-30 22:08 gcov_exp.c.gcov -rw-rw-r-- 1 windriver windriver 168 2011-08-30 22:08 gcov_exp.gcda -rw-rw-r-- 1 windriver windriver 572 2011-08-30 22:06 gcov_exp.gcno [windriver@windriver-machine ltest]$ cat gcov_exp.c #include<stdio.h>int main(void)
{int i,total;
total = 0;for(i=0;i<10;i++)
{ total+=i; }if(total!=45)
printf("Failure\n"); else printf("Success\n"); return 0; } [windriver@windriver-machine ltest]$【6】环境变量读写,使用getenv/setenv/unset
【7】基本数学函数 abs(计算×××数的绝对值|a|),cos(取余玄函数值),ceil(取不小于参数的最小×××数) exp(计算指数),sqrt(计算平方根值) pow(计算次方值) log10计算对数值,注意其中abs在stdlib中,而其它是在math.h库中,因此,编译时需要链接库选项-lm。
[windriver@windriver-machine ltest]$ vi com_fun.c
[windriver@windriver-machine ltest]$ gcc com_fun.c -lm [windriver@windriver-machine ltest]$ ./a.out |-12| = 12 cos(0.5) = 0.877583 sqrt(200) = 14.142136 2^10 = 1024.000000 log10(100) = 2.000000 4.800000=>5.000000 1.120000=>2.000000 -2.200000=>-2.000000 [windriver@windriver-machine ltest]$ cat com_fun.c #include <math.h> #include <stdio.h>int main(void)
{ double answer,root,powvalue,logv; double value[] = {4.8,1.12,-2.2,0}; int i,absvalue; absvalue = abs(-12); answer = cos(0.5); root = sqrt(200); powvalue = pow(2,10); logv = log10(100); printf("|-12| = %d\n",absvalue); printf("cos(0.5) = %f\n", answer); printf("sqrt(200) = %f\n",root); printf("2^10 = %f \n", powvalue); printf("log10(100) = %f\n",logv); for(i=0;value[i]!=0;i++) { printf("%f=>%f\n",value[i],ceil(value[i])); } return 0; } [windriver@windriver-machine ltest]$