随笔分类 - Linux编程
摘要:写了一个测试磁盘寻道(+旋转)时间的程序,方法如下:创建一个大文件(如果太小,文件所有内容都在一个磁道上),使O_DIRECT打开文件,随机选择一个位置(4k的倍数),读取4K(文件系统块)大小的数据。测试程序分别执行1、10、100、1000、10000次随机读文件操作,结果发现在1000次以内,消耗的时间总是1-3ms,超过10000才会略有大的增长,但也在1s范围内。发现DIRECTIO根本没有生效,百思不得其解。仔细阅读了man手册上关于O_DIRECT的说明:Try to minimize cache effects of the I/O to and from this file.
阅读全文
摘要:1. linux提供opendir、readdir(readdir_r)、closedir和scandir等接口实现对目录的读取;2. readdir返回指向下一个目录项的指针,如果要自己传入缓冲区存储目录项,应使用readdir_r代替。readdir的结果中包含当前目录和上一级目录的目录项信息。3. 在遍历过程中,进程的工作目录不会改变,在递归遍历的时候,需要改变工作目录(chdir)以识别相对路径,或者每次都限定全局路径。4. 深度优先遍历目录树采用递归实现易编码(参见如下代码),广度优先遍历则需借助队列实现。当目录下的文件数量较少时,采用广度优先遍历效率会更高,因目录下的目录项基本都是
阅读全文
摘要:Linux环境下,在内核写程序限制很多,相比用户态程序:
n 不能使用C库
n 不能使用系统调用
n 理解内核各个部分的实现原理及相关函数的机制及作用
n 熟悉内核使用的锁机制并仔细处理跟锁相关的细节 之前做过将一个用户态的加密库(包括AES和RSA的实现)移植到内核态使用,主要涉及调试消息的打印,内存空间申请与释放,数据类型的转换,随机数的生成等问题。 没有printf,如何打印消息?
内...
阅读全文
摘要:对于很多服务来说,在同一个服务器上只能运行一个实例,那么通过什么方法来保证程序同一时刻只有一个实例运行呢?通过编写shell脚本来管理程序的启动、停止是个不错的方法。在启动时,shell脚本会创建进程标识文件(存储正在运行实例的pid)以表明已经有实例在运行,如果文件已存在,则说明已有实例在运行,不需要做任何事;在退出时,shell脚本会删除进程标识文件,表明没有实例运行。shell脚本管理方法在应用程序之上再包了一层,那么能不能直接在程序开始运行时自己判断是否有实例在运行呢,答案是肯定的。原理其实差不多,还是要借助公用资源---文件,当然不仅仅是文件而已,还需要文件锁的支持。大致思路是这样的
阅读全文
摘要:在linux系统下创建守护进程的原理及步骤在文章(链接如下)中介绍过。http://blog168.chinaunix.net/space.php?uid=20196318&do=blog&id=28738其实,linux提供了daemon函数用于创建守护进程,实现原理与上文中介绍的是一样的。#include <unistd.h>int daemon(int nochdir, int noclose);1.daemon()函数主要用于希望脱离控制台,以守护进程形式在后台运行的程序。2.当nochdir为0时,daemon将更改进城的根目录为root(“/”)。3.当
阅读全文
摘要:上周在做测试的时候,我的VirtualBox的磁盘文件不幸损坏,不能打开了,又没有做备份,所以只好放弃VB。改用以前用的VMware,结果用了两天除了意想不到的问题,VMware产生的文件居然占据了整个分区,每次都提示系统没有足够的空间,VMware不能启动,分区有40+G,被占满主要是做了多次快照(后来删除了快照,相关的文件没有清理掉,VMware一直卡在那里),额外建立了几个磁盘(配置MD时新建的,并且所有的磁盘的空间都是创建时分配的,而不是动态增长)。在解决问题时误删了一些文件,系统提示找不到启动必须的文件xxx,其实应该删除后来新建的磁盘的,可惜当时有点急,那是已经是周三了,周四有事,
阅读全文
摘要:很多应用需要客户首先进行注册,然后使用用户名、密码进行验证,之前在为一个分布式系统添加认证模块的时候,遇到一个问题,这里进行简要的分析。认证的两种主要形式:1. 单机登录认证:如windows、linux系统用户登录,这种应用的程序代码通常是不公开的,用户要正常的使用系统,必须越过这一障碍。2. 网络登录认证:如QQ、飞信等聊天软件的用户登录,这种应用的代码可以是开源的,因为即使即使代码开源,hacker去掉了客户认证的代码,重新编译运行,服务器发现记录客户端的登录状态为未登录,客户端还是不能继续工作。项目中遇到的问题:客户端通过挂载后,像使用本地文件系统一样使用远程文件系统。登录认证在挂载的
阅读全文
摘要:实现linux登录验证的程序,要考虑两个部分,第一是用户名、密码的输入;第二是用户、密码的验证,关于第二部分的机制已经在http://blog168.chinaunix.net/space.php?uid=20196318&do=blog&id=94771中讲到。而第一部分的难点则在于如何在输入密码时不回显输入的字符,这就需要更改终端的属性,涉及终端IO的编程,主要用到tcgetattr和setattr两个函数,通过取消终端的ECHO标记,即可禁用终端回显,在密码输入处理之后,要记得恢复终端原来的属性,避免影响到其它的进程。终端IO处理大致过程如下:structtermios
阅读全文
摘要:本文更正http://blog168.chinaunix.net/space.php?uid=20196318&do=blog&id=28742中出现的几个错误。错误1:对salt的描述;错误2:密码验证方式。花了点时间研究了一下linux的密码认证机制,当系统启动出现login时,用户登录的过程是如何得到验证的。首先linux系统里管理用户及密码的两个重要的文件,/etc/passwd, /etc/shadow。/etc/passwd包含各个用户的信息,linux平台包含七个字段,各个字段间用冒号隔开,分别是:用户名:密码:用户id:组id:用户描述:用户家目录:用户的登录s
阅读全文
摘要:ldd查看应用程序链接了哪些动态库。 nm列出目标文件中包含的符号信息。size列出各个段的大小及总的大小。strings列出文件中的字符串。readelf读取elf文件的完整结构。objdump导出目标文件的相关信息(elf文件相关工具的源头)。gdb对文件的执行过程进行调试分析,设置断点(b)、单步执行(n)、函数调用追踪(bt)、反汇编(disassemble)。strace跟踪程序中的系统调用及信号处理信息。LD_DEBUG通过设置这个环境变量,可以方便的看到 loader 的加载过程(包括库的加载,符号解析等过程),使用【LD_DEBUG=help 可执行文件路径】可查看使用帮助。L
阅读全文
摘要:Man page of xargs
xargs reads items from the standard input, delimited by blanks (which can be protected with double or single quotes or a backslash) or newlines, and executes the command (default is...
阅读全文
摘要:http://blog.chinaunix.net/u2/87570/showart_2048930.html介绍了如何编写守护进程,其实linux提供了将进城在后台运行的函数daemon。#include <unistd.h>int daemon(int nochdir, int noclose);1. daemon()函数主要用于希望脱离控制台,以守护进程形式在后台运行的程序。2. 当nochdir为0时,daemon将更改进城的根目录为root(“/”)。3. 当noclose为0是,daemon将进城的STDIN, STDOUT, STDERR都重定向到/dev/null。
阅读全文
摘要:Linux系统的系统调用通过设置全局errno来标示错误类型http://blog.chinaunix.net/u2/87570/showart_2137607.html,并通过perror,sperror函数提供对errno的解析。而我们平时写程序的错误处理方式类似于下面的代码:if ( p == NULL ){ printf ( "ERR: The pointer is NULL\n" );}if(socket(PF_INET, SOCK_STREAM, 0) < 0) {printf(“create socket errr\n”);}这种方式虽然没什么问题,但其
阅读全文
摘要:l 符号表链接过程的本质就是把多个不同的目标文件之间相互粘在一起。在链接中,目标文件之间相互拼合实际上是目标文件之间对地址的引用,即对函数和变量(函数,变量统称符号)的地址的引用。符号是链接过程中的粘合剂,整个链接过程是基于符号引用完成的,链接过程中很关键的一部分就是符号的管理,每一个目标文件都会有一个相应的符号表(Symbol Table),这个表里面记录了目标文件中用到的所有符号。每个定义的符号有一个对应的值,叫做符号值,对于变量和函数来说,符号值就是它们的地址。符号主要包括定义在本文件内的全局符号,在本文件中引用的全局符号(但定义在其它文件),段名,局部符号,行号信息(目标文件指令与源代
阅读全文
摘要:程序设计的模块化是程序员们一直在追求的目标,因为当一个系统十分复杂时,我们不得不将一个复杂的系统逐步分割成小的系统以达到各个击破的目的。复杂的软件也是如此,程序员把每个源代码模块独立的编译,然后按照需要将它们组装起来,这个组装模块的过程就是链接。链接的主要内容就是把各个模块之间相互引用的部分都处理好,使得各个模块之间能够正确地链接,链接过程主要包括地址和空间分配,符号决议和重定位等步骤。链接过程如下图所示: 如程序模块main.c中使用了另外一个模块中的func.c中的函数foo(),在main.c中的每一次调用foo函数时都必须知道foo的确切地址,但由于每个模块都是单独编译的,在编译mai
阅读全文
摘要:以helloworld为例分析gcc编译过程:#include <stdio.h>int main(){ printf(“Hello World\n”); return 0;}通常我们使用gcc来生成可执行程序,命令为:gcc hello.c,生成可执行文件a.out实际上gcc hello.c可以分解为4个步骤,分别是预处理(Preprocess),编译(Compilation),汇编(Assembly)和链接(Linking),如下图所示:1 预编译gcc –E hello.c –o hello.i,以下为预处理后的输出文件hello.i的内容# 1 "hello.c
阅读全文
摘要:/** 使用信号实现父子进程之间的同步** TELL_WAIT(): set things up for TELL_xxx & WAIT_xxx * TELL_PARENT(): tell parent we are done* WAIT_PARENT(): wait for parent* TELL_CHILD(): tell child we are done* WAIT_CHILD(): wait for child** SIGUSR1: the signal parent sends to child* SIGUSR2: the signal child sends to pa
阅读全文
摘要:autotools的使用流程autoscan->aclocal->autoconf-> automake->configure以helloworld为例加以说明:1)新建helloworld.c,并修改代码如下: int main(int argc,char** argv) { printf("hello world!"); }2)autoscan:autoscan:生成configure.scan3)编辑configure.scan,并重命名为configure.in 内容如下: # -*- Run autoconf -*-# Process th
阅读全文
摘要:最近准备花点时间学习下shell脚本语言,一是考虑到对以后找工作有帮助,因为很多上班了同学还有去面试的同学都说有的公司还是比较看重写shell脚本这个技能的,二是自己的工作需要,可能要写一些简单的脚本,虽然刚学linux时看《鸟哥的私房菜》时学过点皮毛,但现在已经忘的差不多了,刚好借这个机会系统学习一下。先将基础知识复习了一下,为进一步深入学习做准备。Shell脚本第一行的#!当一个文件中开头的两个字符是#!时,内核会扫描该行其余的部分,看是否存在可用来执行程序的解释器的完整路径(中间如果出现任何空白符号都会略过),此外内核还会扫描是否有一个选项要传递给解释器,内核会以被指定的选项来引用解释器
阅读全文
摘要:Linux可执行文件为ELF格式,ELF格式文件主要分为以下几类:1. 可重定位文件(Relocatable File),这类文件包含了代码和数据,可以被用来链接成可执行文件或共享目标文件,静态链接库也可以归为这一类,如.o文件。2. 可执行文件(Executable File),这类文件包含了直接执行的程序,如/bin/bash等。3. 共享目标文件(Shared Object File),链接器可以使用这种文件跟其他的可重定位文件和共享目标文件链接,产生新的目标文件;动态链接器可以将几个共享目标文件与可执行文件结合,作为进程映像的一部分来运行,如glibc***.so。4. 核心转储文件(
阅读全文
浙公网安备 33010602011771号