unix高级环境编程 例子 代码实现练习 第七章:进程环境

程序清单 7-1 经典c程序 P148

/**
 * 程序清单 7-1 经典c程序 P148
 *
 * zy:
 * 注意这个经典的c程序是不完整的,没有返回值,没有声明main的返回类型
 * 才会造成这样的情况
 * 这是因为直接返回了main中栈和寄存器的内容
 *
 * 书上说返回码的是随机的,但是我始终得到8
 *
 */


main() {
	printf("hello!");
	//return 0;加了这句返回码就是0,并且与exit(0)是一个意思,这样内核会帮助我们做一些清理工作,比如关闭打开的文件
}
结果:

asd@asd-desktop:~/workspace/test/src$ ./a.out 
hello!asd@asd-desktop:~/workspace/test/src$ echo $?
8

程序清单 7-2 终止处理程序实例 P150

/**
 * 程序清单 7-2 终止处理程序实例 P150
 *
 * zy:
 * atexit函数,使用这个函数可以注册一些函数,
 * 注册的函数在main函数调用return和exit时候调用
 * 可以帮助我们处理一些事
 *
 * 注意注册顺序和调用顺序相反,有点类似于栈
 *
 */

#include "apue.h"
#include "error.c"
static void my_exit1(void){
	printf("first exit handler\n");
}
static void my_exit2(void){
	printf("second exit handler\n");
}

int main() {
	if(atexit(my_exit2)!=0){//my_exit2作为一个函数,没有参数的()括号
		err_sys("can't register my exit2");
	}
	if(atexit(my_exit1)!=0){
		err_sys("can't register my exit1");
	}
	if(atexit(my_exit1)!=0){
		err_sys("can't register my exit1");
	}
	printf("main is done\n");
	return 0;
}
结果:

main is done
first exit handler
first exit handler
second exit handler
asd@asd-desktop:~/workspace/test/src$ 

程序清单 7-3 将所有命令行参数回送到标准输出上

/**
 * 程序清单 7-3 将所有命令行参数回送到标准输出上 P151
 *
 * zy:
 * 执行一个新的进程的时候,调用exec的进程会可以将命令行参数传递给新程序
 */


#include "apue.h"
#include "error.c"
int main(int argc, char **argv) {
	int i;
	for(i=0;i<argc;i++){//也可以改为for(i=0;argv[i]!=NULL;i++){ 因为argv[argc]==NULL,这是规定
		printf("argv[%d] : %s \n",i, argv[i]);
	}
	exit(0);
}

结果:

asd@asd-desktop:~/workspace/test/src$ ./a.out 123 321 222 111
argv[0] : ./a.out 
argv[1] : 123 
argv[2] : 321 
argv[3] : 222 
argv[4] : 111 
asd@asd-desktop:~/workspace/test/src$ 

程序清单 7-4 进行命令处理的典型框架

这是一段学习使用setjmp和longjmp的框架,不能实际运行,只是讲解用,所以就不抄了

程序清单 7-5 setjmp和longjmp实例

这是一段学习使用setjmp和longjmp的框架,不能实际运行,只是讲解用,所以就不抄了
程序清单 7-6 可以实际运行。

程序清单 7-6 longjmp对各类变量的影响

/**
 * 程序清单 7-6 longjmp对各类变量的影响 P164
 *
 * zy:
 * 不仅能看到使用longjmp是如何使函数进行了跳转,
 * 还能够看出自动变量、全局变量、寄存器变量、静态变量、易失变量的变化
 *
 * 结论:全局和静态、易失变量不会受到优化的影响。
 */

#include "apue.h"
#include "error.c"
#include <setjmp.h>

static void f1(int,int,int,int);

static void f2(void);

static  jmp_buf jmpbuffer;
static int globval;

int main(int argc, char **argv) {
	int autoval;
	register int regival;
	volatile int volaval;//强制访存操作,防止编译器去优化,告诉编译器每次必须去内存中取值,而不是从寄存器或者缓存.
	static int statval;

	globval=1;
	autoval=2;
	regival=3;
	volaval=4;
	statval=5;

	if(setjmp(jmpbuffer)!=0){
		printf("after longjmp: \n");
		printf("globval = %d, autoval=%d,regival = %d ,volaval = %d,statval=%d\n"
				,globval,autoval,regival,volaval,statval);
		exit(0);
	}

	globval=95;
	autoval=96;
	regival=97;
	volaval=98;
	statval=99;

	f1(autoval,regival,volaval,statval);
	exit(0);//我们的设计是不可能从这里结束函数的。

}

static void f1(int autoval,int regival,int volaval,int statval){
	printf("in f1()\n");
	printf("globval = %d, autoval=%d,regival = %d ,volaval = %d,statval=%d\n"
			,globval,autoval,regival,volaval,statval);
	f2();
}
static void f2(void){
	longjmp(jmpbuffer,1);
}

结论:

asd@asd-desktop:~/workspace/test/src$ gcc test.c 
asd@asd-desktop:~/workspace/test/src$ ./a.out 
in f1()
globval = 95, autoval=96,regival = 97 ,volaval = 98,statval=99
after longjmp: 
globval = 95, autoval=96,regival = 97 ,volaval = 98,statval=99
asd@asd-desktop:~/workspace/test/src$ gcc -O test.c 
asd@asd-desktop:~/workspace/test/src$ ./a.out 
in f1()
globval = 95, autoval=96,regival = 97 ,volaval = 98,statval=99
after longjmp: 
globval = 95, autoval=2,regival = 3 ,volaval = 98,statval=99
asd@asd-desktop:~/workspace/test/src$ 

程序清单 7-7 自动变量的不正确使用

/**
 * 程序清单 7-7 自动变量的不正确使用 P164
 *
 * zy:
 * 这是一种错误的使用方式,就是不能这么用,因为
 * 声明自动变量的函数已经返回后,不能引用这个自动变量了
 *
 * 正确的方式:使用全局存储的静态变量或者是动态地为其分配空间
 */


#include <stdio.h>


#define DATAFILE "datafile"


FILE *open_data(void){
	FILE *fp;
	char databuf[BUFSIZ];


	if((fp=fopen(DATAFILE,"r"))==NULL)
		return NULL;
	if(setvbuf(fp,databuf,_IOLBF,BUFSIZ)!=0)
		return NULL;
	return fp;//这句是错误的,因为其是自动变量
}

程序清单 7-8 打印当前资源限制 P166

/**
 * 程序清单 7-8 打印当前资源限制 P166
 *
 * zy:
 * 下面的程序打印了系统所支持的资源的软限制和硬限制,
 * 代码中,我们包含了各个资源的名字
 * 而各个资源的含义请查看书籍165
 */

#include "apue.h"
#include "error.c"
#if defined (BSE)||defined (MACOS)
#include "sys/time.h"
#define FMT "%10lld"
#else
#define FMT "%10ld"
#endif
#include <sys/resource.h>

#define doit(name) pr_limits(#name,name)

static void pr_limits(char *,int);

int main(int argc, char **argv) {
#ifdef RLIMIT_AS
		doit(RLIMIT_AS);
#endif
		doit(RLIMIT_CORE);
		doit(RLIMIT_CPU);
		doit(RLIMIT_DATA);
		doit(RLIMIT_FSIZE);
#ifdef RLIMIT_LOCKS
		doit(RLIMIT_LOCKS);
#endif
#ifdef RLIMIT_MEMLOCK
	doit(RLIMIT_MEMLOCK);
#endif
	doit(RLIMIT_NOFILE);
#ifdef RLIMIT_NPROC
	doit(RLIMIT_NPROC);
#endif
#ifdef RLIMIT_RSS
	doit(RLIMIT_RSS);
#endif
#ifdef RLIMIT_SBSIZE
	doit(RLIMIT_SBSIZE);
#endif
	doit(RLIMIT_STACK);

#ifdef RLIMIT_VMEM
	doit(RLIMIT_VMEM);
#endif
	exit(0);

}
static void pr_limits(char *name ,int resource){
	struct rlimit limit;
	if(getrlimit(resource,&limit)<0){
		err_sys("getrlimit error for %s",name);
	}
	printf("%-14s",name);
	if(limit.rlim_cur==RLIM_INFINITY){
		printf("(infinite)");
	}else {
		printf(FMT,limit.rlim_cur);
	}
	if(limit.rlim_max==RLIM_INFINITY){
		printf("(infinite)");
	}else {
		printf(FMT,limit.rlim_max);
	}
	putchar((int)'\n');
}

结果:
asd@asd-desktop:~/workspace/test/src$ ./a.out 
RLIMIT_AS     (infinite)(infinite)
RLIMIT_CORE            0(infinite)
RLIMIT_CPU    (infinite)(infinite)
RLIMIT_DATA   (infinite)(infinite)
RLIMIT_FSIZE  (infinite)(infinite)
RLIMIT_LOCKS  (infinite)(infinite)
RLIMIT_MEMLOCK     65536     65536
RLIMIT_NOFILE       1024      4096
RLIMIT_NPROC       15970     15970
RLIMIT_RSS    (infinite)(infinite)
RLIMIT_STACK     8388608(infinite)
asd@asd-desktop:~/workspace/test/src$ 



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值