Unix环境编程二

前言

之前写过一篇,但是当时理解还很初级,而今重读,并且已经看了网络编程,对IO/网络编程有了更好的认识,相信重读也会有新的收获。最终会把之前的文章删掉,只保留这一篇。

系统限制

可以使用的获取系统限制的方法:1)通过命令行getconf;2)通过sysconf和pathconf系统调用。前者的所有可用选项可以通过查看后面的文档取得。可以使用strace查看getconf的实现。实际上,getconf并不是调用sysconf实现的,而是getrlimit。当IDE没法自动倒入一些常量时,grep/find是很好的工具。头文件一般都包含在/usr/include 或者/usr/lib/gcc/$version/include下,其中version 是gcc版本。

getconf -a 
getconf ARG_MAX # <=> sysconf(_SC_ARG_MAX)
getconf _POSIX_NAME_MAX /usr # <=> getconf NAME_MAX /usr

文件

当调用open时,产生的文件描述符的关系和多进程相近,每个文件描述副都有自己的文件表项,和dup产生的文件描述符不同。这意味着使用open打开的文件描述符有各自的文件偏移量,但是同一个文件描述符的读写共享一个偏移量。产生的子进程和dup类似。dup2允许指定文件描述符,如果fd2已经打开,则现将其关闭。新描述符的执行关闭标志为总是被关闭,并且dup2时原子的。

获取文件状态的函数fcntl 

int flag = fcntl(fd2, F_GETFL, 0);

进程环境

exit调用做的事情:1)FIFO调用通过atexit注册的方法;按需调用多次fclose,关闭打开流;如若程序调用 exec族任意一个函数,则清除所有已安装的终止程序;

典型存储空间布局,x86处理器上的Linux,正文段是从0x08048000开始,栈底从0xC0000000开始。可以通过在不同位置声明变量打印地址来查看地址的分配。在Linux上,并不总是按照以上规则,堆和栈的地址看上去有一定的随机性,尤其是栈。但是确定的是,栈的地址总是比堆要高,并且环境变量地址和栈是挨着的。bss和初始化变量区地址也相对固定。

环境变量(__environ)的访问对应3个方法,setenv/putevn/getenv.其中putenv接受一个"KEY=VALUE"的字符串,但是必须保证字符串存储地址的生命周期比环境变量要长,否则会引起问题。setenv则会拷贝KEY和VALUE字符串。初始时环境变量存储在栈底以下位置(比栈底地址更高),如果对环境变量修改,修改之后占用存储区比以前小,没有问题。但是如果赋值后的环境变量比以前大,则会把环境变量拷贝到堆区。可以通过观察__environ的地址来验证这种变化。

内存分配函数malloc/calloc/realloc; malloc分配一块内存,其中的值不确定;calloc分配一块内存,并且都初始化为0;realloc则分调整以分配内存的大小。这些都是库方法,实际会调用brk和sbrk系统调用。

使用setjmp和longjmp可以实现类似于try-catch的效果,即从更深层次的函数调用直接返回到上层。

jmp_buf buf;

void func1(int i) {
    printf("in func1, i is: %d\n", i);
}

void func2(int i) {
    printf("in func2, i is: %d\n", i);
    if (i == 2) {
        longjmp(buf, 2);
    } else {
        func1(i);

    }
}

void func3(int i) {
    printf("in func3, i is: %d\n", i);
    if (i == 3) {
        longjmp(buf, EWOULDBLOCK);
    } else {
        func2(i);
    }
}

int main() {
    volatile int i = 4;
    setjmp(buf);
    i--;
    func3(i);
}

创建子进程之后,父子进程同时都标准输入,看到的现象是父子进程交替读取标准输入的数据,不是两个进程都会读到所有数据。父子进程创建后的关系如下,为了避免父子进程的影响,父子进程分别关闭不再使用的描述符是常用手段,例如网络文件描述符。

errno是线程安全的,每个线程都有自己的errno。每个调用只在出错时设置errno,但是正确返回情况不会有线程对errno清零。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值