库函数和系统调用的区别
库函数是更高级别的,完全在用户空间里运行,并为程序员提供了更方便的做实际工作的函数接口。Higher level,run in user space,more convenient。
系统调用代表用户以内核模式工作,由操作系统本身的内核提供。In kernel mode。
库函数printf看上去类似于一般输出函数,但是它实际上只是格式化你提供给字符串的数据,并用低级系统调用write编写字符串数据,然后将数据发送到一个与终端的标准输出关联的文件中。
DiFX使用中遇到/usr/bin/ld can not find –fl
这个主要是因为安装DiFX时没有把安装包装全。
可以参考CentOS 安装DiFX。
解决方法为安装flex*,全包(包括开发库)而不只是flex。
在使用difx的install附加安装HOPS的时候,报错说是-lpng12没有找到,自己看了一下,丫的libpng我装了呀,使用yum search了一下,发现libpng还有libpng10、libpng12,囧。
解决方法很简单:
1 | yum install libpng12* |
当然,对于centos而言,如果找不到这个package,可以去http://fr2.rpmfind.net/linux/rpm2html/search.php?query=libpng12.so.0&submit=Search+…&system=centos&arch=进行下载,直接安装rpm包也是ok的。
在安装DiFX的时候出现这个问题。
运行install.sh出现:
ERROR: Unable to find rpm tool, please add its location to your PATH and restart installation
Installation failed.
Please see /var/log/ipp_em64t_install.log for details.
Installation is complete:
Thank you for using Intel Software Development Products, tools for improving application performance.
解决方法为: /install/install –nonrpm
这个bug在ipp5.3和ipp6.0都是存在的,从ipp6.1开始修复,对于全新的IPP,多个版本可以共存安装。
DiFX中getEOP.py问题
使用getEOP.py的时候出现
1 | ImportError:No module named mx.dateTime |
缺少mx包,解决方法使用yum install python-egenix-mx-base
即可。
最新更新,直接执行
startCalcServer
即可解决这个问题了。
我记得去年貌似就碰到这个问题,不过只是不同的发行版而已,今天是Fedora
17,Pro.Z的机器。
问题就是difx的calcserver程序是需要调用rpc的,而大部分情况下,出错的原因是因为rpc支撑环境没有安装,其实如果使用了NFS,这个问题一般是没有问题的。
解决方法少许有些不同,不过还是可以只使用的:即安装portmap程序包,然后尝试service rpcbind start
。
1 | $ apt-get install portmap |
这里很高兴还记得ALT+F2,然后r重启X11 shell的技巧。
关于difx的troubleshooting也有提及RPC service unavailable
If an RPC error is encountered when starting the calcserver program, it is possible that the portmap service is either not installed or not running. Please consult your OS distribution documentation for rectifying this. In the case of Debian or Ubuntu Linux, the solution may be as simple as:
端口映射是一个服务器,将RPC程序号转换为DARPA的协议端口号。在使用RPC调用时它必须运行。
portmap进程的主要功能是把RPC程序号转化为Internet的端口号。
当一个RPC服务器启动时,会选择一个空闲的端口号并在上面监听(每次启动后的端口号各不相同),同时它作为一个可用的服务会在portmap进程注册。一个RPC服务器对应惟一一个RPC程序号,RPC服务器告诉portmap进程它在哪个端口号上监听连接请求和为哪个RPC程序号提供服务。经过这个过程,portmap进程就知道了每一个已注册的RPC服务器所用的Internet端口号,而且还知道哪个程序号在这个端口上是可用的。portmap进程维护着一张RPC程序号到Internet端口号之间的映射表,它的字段包括程序号、版本号、所用协议、端口号和服务名,portmap进程通过这张映射表来提供程序号-端口号之间的转化功能
如果portmap进程停止了运行或异常终止,那么该系统上的所有RPC服务器必须重新启动。首先停止NFS服务器上的所有NFS服务进程,然后启动portmap进程,再启动服务器上的NFS进程。
远程过程调用(Remote Procedure Call,RPC
)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用。
C语言中有很多的语句:空语句、表达式语句、代码块、if语句、while语句、break和continue语句、for语句、do语句、switch语句、switch中的break语句、default子句、goto语句。
基本上,C语言实现了其他现代高级语言所具有的所有语句。
在C的if语句和其他语言的if语句中,只存在一个差别:就是C不具备布尔类型,而是用整型来代替。
对于if-else配对的问题,else字句从属于最靠近它的不完整的if语句。
在while语句中,使用break语句可以永久终止循环,而使用continue语句,用于永久终止当前的那次循环。这两条语句的任何一条如果出现于嵌套的循环内部,它只对最内层的循环起作用,你无法使用break或者continue语句影响外层循环的执行。
有时while语句在表达式中就可以完成整个语句的任务,于是循环体就无事可做,此时单独用一行表示一条空语句是比较好的做法,比如:
1 | while((ch = getchar() ) != EOF && ch != ‘\n’) |
for语句的形式为:
1 | for (expression1; expression2; expression3) |
其中expression1称为初始化部分,expression2称为条件部分,expression3称为调整部分。
与上述for语句相同意义的while语句:
1 | expression1; |
从上面两个语句的对比,我们可以看出,for循环有一个风格上的优势,就是把所有用于操纵循环的表达式收集在一起,放在同一个地点,便于寻找。
do语句
当你需要循环体至少执行一次时,选择do语句。
switch语句中的执行中遇到了break语句,执行流就会立即跳到语句列表的末尾。而break语句的实际效果是把语句列表划分为不同的不同,这样,switch语句就能够按照更为传统的方式工作。其实如果这样的话,那么最后一个语句就不用添加break了,但是还是加上了break,主要是在以后的维护中,如果维护人员添加代码而忘记了break就有可能影响程序的效果。
default子句
对于switch中的default语句,我一直认为要放在最后,但是测试了一下,发现default可以出现在任何一个case标签出现的地方而不仅仅是最后。
对于符合多个case的情况,最好写上注释,防止在检查的时候额外加上了break而导致出现bug。
goto语句可以出现在函数中的任何一个位置,这种无序的跳转是很危险的,所以,如果有其他方法搞定,最好少用goto语句。
当然,针对跳转出多层嵌套,goto确实是一种比较方便的方法。当然可以使用一个标志值,来跳转出所有的循环,或者将所有的循环放在一个函数中,直接使用return来跳出。对于设置标志值,例如:
1 | enum {EXIT,OK} status; |
另外还需要注意:C并不具备任何的输入输出语句,IO是通过调用库函数实现的,C也不具备任何异常处理语句,它们也是通过调用库函数来完成的。
由于结构体的成员不一定是连续地存储在内存中,所以不能用运算符==或!=来对结构体进行比较,事实上,在一个结构体的存储区域内可能会出现一些“空洞”,这是由于计算机是按照一定的边界,例如半字、字、双字边界来存储不同数据类型的变量。
在传递一个结构体时,用传地址的方式比采用传值的方式效率高,因为传值会要求复制整个结构体。
这里由引出来另一个比较有意思的问题,既然结构体的变量可以不同类型的,当然结构体也可以作为内部变量,如下所示,shao_struct_v2.c
1 | #include <stdio.h> |
1 | ➜ struct git:(master) ✗ gcc shao_struct_in_struct.c |
用户输入信息需要访问到结构体变量所在的内存空间地址
1 | #include<stdio.h> |
1 | #include<stdio.h> |
1 | #include<stdio.h> |
执行当前文件夹下的可执行程序,不加”./”的方法:
直接执行当前目录下的程序可以使用一下方法:
执行当前可执行程序加”./”的原因:
主要是安全原因,因为在linux中执行程序时,会先搜索当前目录然后是系统目录,所以如果当前目录中有与系统可执行程序重名的程序,比如cp,她就会优先执行当前目录中的cp,但是如果当前目录的cp是木马,就会威胁到系统安全,所以这是Linux的一种安全策略,所以默认并没有把当前目录加到环境变量PATH中去。