• UNIX环境高级编程--7


    进程环境
    main函数:
        C程序总是从main函数开始执行。main函数原型是:
        int main(int argc, char *argv[]);
        当内核执行C程序时(使用一个exec函数),在调用main前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址--这是由链接编译器设定的,而链接编辑器则由c编译器调用。启动例程从内核取得命令行参数和环境变量值然后按上述方式调用main函数做好安排。

    进程终止:
        8种方式使进程终止。其中5种为正常终止:
        (1)从main返回;
        (2)调用exit
        (3)调用_exit或_Exit;
        (4)最后一个线程从其启动例程返回
        (5)从最后一个线程调用pthread_exit
        异常终止3种:
        (6)调用abort
        (7)接到一个信号
        (8)最后一个线程对取消请求做出相应
        
    函数atexit:
        ISO C规定,一个进程可以登记至多32个函数,这些函数将由exit自动调用。我们称这些函数为终止处理程序(exit handler),并调用atexit函数来登记这些函数。说白了就是当main函数将要结束的时候,自动会调用这些注册好的exit函数(和注册顺序相反)。
        
        
    环境表:
        char *envp[]:每个程序都有一个环境表。与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以null结束的c字符串的地址。
        在历史上,大多数UNIX系统支持main函数代3个参数,第三个参数就是环境表。
        
    C程序的存储空间布局:
        (1)正文段(代码区)。CPU执行的机器指令部分。只读。
        (2)初始化数据段。数据段。包含了程序中需明确附初始值的变量。例如C程序中任何函数之外的声明。都存储在数据段中。
             int maxcount = 99;
        (3)未初始化数据段。bss段。在程序开始执行前,内核将此段中的数据初始化为0或者空指针。
             long sum[1000];
        (4)栈。递归函数每次调用自身时,就用一个新的栈帧,因此一次函数调用实例中的变量集不会影响另一次函数调用实例中的变量。
                栈底在0xC0000000之下开始,所以栈地址从高地址向低地址方向增长。
        (5)堆。

    共享库(动态链接库.so):
        so == share object 在程序的链接时并不像静态库那样在拷贝使用函数的代码,只是做简单的标记。然后在程序开始启动的时候,动态加载所需要模块。所以,应用程序在运行的时候仍然需要共享库的支持。因此,共享库链接出来的文件比静态库要小很多,但是对.so文件的依赖更强。
        假设源代码在foo.c文件离并且将创建成foo.so的共享库。中介对象文件叫foo.o。共享库可以包含多个对象文件。
        创建共享库和链接可执行文件类似:先把源代码编译成目标文件,然后把目标文件链接起来,目标文件需要创建成位置无关码PIC(position-independent code)。
        (1)创建PIC
        略。。。


    *静态库(静态链接库.a):    
        静态链接库是一些目标文件的集合,以.a结尾。在程序链接的时候使用,链接器会将程序中使用到函数的代码从库文件中拷贝到应用程序中。一旦链接完成,在执行的时候就不需要静态链接库了。由于使用静态链接的程序都需要拷贝所用函数,所以文件会比较大。
        创建与应用:
            (1)首先创建库文件libhello.c
            #include
            void hello()
            {
                printf("hello, welcome to library world! ");
            }
            (2)创建头文件libhello.h
            void hello();
            (3)创建libhello静态库文件:
            $ gcc -c libhello -o libhello.o
            $ ar rcs libhello.a libhello.o
            其中ar中的rcs的意思是: r表明将模块加入到静态库中,c表示创建静态库,s表示生产索引。

            我们写一个测试程序:
            $ cat test.c
            #include
            int main(void)
            {
            printf("use library hello. ");
            hello();
            return 0;
            }

            (4)编译与链接:
            $ gcc -c test.c -o test.o
            $ gcc test.o -L. -lhello -o test
            说明:-L.表示将当前目录加入到库搜索路径。默认的库搜索路径在/usr/lib目录下。
            另外这里说明一下易混淆的参数-I,它表示搜索头文件的路径。这样gcc在查找头文件的时候会首先到-I指定的目录查找,然后才是系统默认目录。

            -l参数: -lname表示库搜索目录下的libname.a 或者libname.so文件 ,这也是为什么库文件都以lib开头的原因之一。一个惯例嘛。当然了,如果你的库文件不是libhello,而是hello. 那就不能用-l参数编译了。 可以这样:
            gcc test.o -L. hello.a -o test

            注意: $gcc -L.-lhello test.o -o test 会出错!。
            原因是: -l是链接器选项,必须要放到被编译文件的后面。 所以上面的命令中-lhello一定要放到 test.o的后面。
            (5)运行:
            $ ./test
            use library hello.
            hello, welcome to library world!

    *动态加载库(So):
        动态加载库(dynamicallyloaded (DL)libraries)指在程序运行过程中可以加载的函数库。而不是想共享库在程序启动的时候加载。DL对实现插件和模块化非常有用,因为他们可以让程序在允许时等待插件的加载。在linux中,二者的文件格式没有区别。


    存储空间分配:
        malloc calloc realloc , calloc为指定数量指定长度的对象分配存储空间。该空间中的每一位都初始化为0;
        未声明函数的默认返回值为int。
        free函数释放ptr指向的存储空间。被释放的空间通常被送入可用存储池。

    替代的存储空间分配程序:
        libmalloc、vamlloc、quickfit、jemalloc、TCMalloc
        alloca:在栈上分配存储空间。没错 实在栈上!栈 之所以是栈 也不过是倒着用内存而已,但是却有奇效啊 , 各种数据结构逻辑顺序递归啊啥的都得以轻松实现,神了。
        
        
    环境变量:
        环境变量形式:name=value
        UNIX内核并不查看这些字符串,他们的解释完全取决于各个应用程序。

    setjmp longjmp函数:
        在栈上函数调用栈可能会多层嵌套,当最底层发生错误时可以通过这两个函数直接返回最上层函数调用处,类似goto语句。
    比如,在main中调用setjmp,并将所需要的信息记入变量jmpbuffer中并返回0,当在函数cmd_add中出出错时,则调用longjmp函数反绕到main函数的对应位置处。也就放弃了其他栈帧。

    限制:
        软限制:内核实际执行的限制,任何进程都可以将软限制设置为任意小于等于进程硬限制的值。
        硬限制:可以在任何时候任何进程中设置,但只能由超级用户提起。

    每天撸一点linux:
    size cc :报告正文段、数据段和bss段的长度
        因为c99(std=c99 : gcc的1999 ISO C拓展) 中不能声明无类型的主函数main所以会给警告,怎么忽略所有警告呢 : -w

  • 相关阅读:
    软件工程15 结对编程作业
    软工网络15个人阅读作业2——提问题
    软件工程网络15个人阅读作业1
    第15周-反射与JSP
    Java课程设计-定时器(团队)
    Java课程设计-定时器
    第14周-数据库
    网络15软工个人作业5——软件工程总结
    软工网络15个人作业4——alpha阶段个人总结
    软工网络15个人作业3——案例分析
  • 原文地址:https://www.cnblogs.com/luntai/p/6141050.html
Copyright © 2020-2023  润新知