• Linux:06进程


    缘起

    • 本章的标题是 chap06:进程

    内容

    0

    • 进程结构 、进程虚拟内存的布局和内容、进程的属性。

    6.1、进程和程序

    • 进程是由内核定义的抽象的实体,并为该实体分配用以执行程序的各项系统资源。

    6.2、进程号和父进程号

    • pid_t getpid(void),头文件是unistd.h

    6.3、进程内存布局

    • 图6-1要烂熟于心
    • 函数要压栈,那么自己malloc()就是堆了,--用这种方法记。
    #include "../lionel_tlpi.h"
    
    char globBuf[65535];  //uninitialized data segment
    int primes[] = { 2,3,5,7 };//initialized data segment
    
    static int square(int x)  // allocated in frame for square()
    {
    	int result;
    	result = x * x;
    	return result;   // return value passed via register
    }
    
    static void doCal(int val)
    {
    	printf("The square of %d is %d
    ",val,square(val));
    
    	if (val < 1000)
    	{
    		int t;  // allocated in frame for doCal()
    		t = val * val * val;
    		printf("The cube of %d is %d
    ",val,t);
    	}
    }
    
    int main(int argc, char** argv[])   // allocated in frame for main()
    {
    	static int key = 9973;//initialized data segment
    	static char mbuf[10240000];//uninitialized data segment
    	char* p; // allocated in frame for main()
    
    	p = malloc(1024);//Points to memory in heap segment
    	doCal(key);
    	exit(EXIT_SUCCESS);
    }
    

    6.4、虚拟内存管理

    6.5、栈和栈帧

    6.6、命令行参数(argc,argv)

    6.7、环境列表

    • export命令
    • printenv命令

    从程序中访问环境

    • 程序6-3:显示进程环境
    #include "../lionel_tlpi.h"
    extern char** environ;
    
    int main(int argc, char* argv[])
    {
    	char** ep;
    	for (ep = environ; *ep != NULL; ep++)
    		puts(*ep);
    	exit(EXIT_SUCCESS);
    }
    
    

    修改环境

    程序示例

    • 程序6-4:修改进程环境(这个没有run)
    #define _GNU_SOURCE  // To get various declarations from <stdlib.h>
    #include "../lionel_tlpi.h"
    
    extern char** environ;
    
    int main(int argc, char* argv[])
    {
    	int j;
    	char** ep;
    
    	clearenv();  // Erase entire environment
    
    	for (j = 1; j < argc; j++)
    	{
    		if (putenv(argv[j]) != 0)
    			//errExit();
    	}
    
    	if (setenv("GREET", "hello world", 0) == -1)
    		//errExit();
    		;
    
    	unsetenv("BYE");
    
    	for (ep = environ; *ep != NULL; ep++)
    		puts(*ep);
    
    	exit(EXIT_SUCCESS);
    }
    
    

    6.8、执行非局部跳转:setjmp()和longjmp()

    • 非局部(nonlocal):是指跳转的目标为当前执行函数之外的某个位置。
    • goto的限制,不能从当前函数跳转到另一函数
    • 先通过setjmp()的初始调用建立一个跳转目标,再用switch检测是初次从setjmp()调用返回,还是在调用longjmp()后返回。
    #include <setjmp.h>
    //#include<stdio.h>
    #include "../lionel_tlpi.h"
    
    static jmp_buf env;
    
    static void f2(void)
    {
    	longjmp(env, 2);
    }
    
    static void f1(int argc)
    {
    	if (argc == 1)
    		longjmp(env, 1);
    	f2();
    }
    
    int main(int argc, char* argv[])
    {
    	int i = setjmp(env); // 我自己写的,原文是switch(setjmp(env))
    	switch (i)
    	{
    	case 0:    // This is the return after the initial setjmp()
    		printf("Calling f1() after initial setjmp()
    ");
    		f1(argc);  // never returns...
    		break;  // but this is good form
    
    	case 1:
    		printf("We jumped back from f1()
    ");
    		break;
    
    	case 2:
    		printf("We jumped back from f2()
    ");
    		break;
    	}
    	exit(EXIT_SUCCESS);   //stdlib.h里的
    }
    
    • 对setjmp()函数的使用限制
      • 选择或迭代语句(if、switch、while)
      • 作为独立的函数调用,没有嵌入到更大的表达式之中
    • 滥用longjmp()
      • 线程甲中用了setjmp(),却在线程乙中调用longjmp(),这是不对的。
    • 优化编译器的问题
      • longjmp()操作会使经过优化的变量被赋以错误值
      • gcc -Ogcc不加编译选项的区别。
    #include <setjmp.h>
    #include "../lionel_tlpi.h"
    
    static jmp_buf env;
    
    static void doJump(int nvar, int rvar, int vvar)
    {
    	printf("Inside doJmp(): nvar=%d rvar=%d vvar=%d
    ",nvar,rvar,vvar);
    	longjmp(env, 1);
    }
    
    int main()
    {
    	int nvar;
    	register int rvar;  // allocated in register if possible
    	volatile int vvar;  // see text
    
    	nvar = 111;
    	rvar = 222;
    	vvar = 333;
    
    	if (setjmp(env) == 0)  // Code executed after setjmp()
    	{
    		nvar = 777;
    		rvar = 888;
    		vvar = 999;
    		doJump(nvar, rvar, vvar);
    	}
    	else {
    		printf("After doJmp(): nvar=%d rvar=%d vvar=%d
    ", nvar, rvar, vvar);
    	}
    	exit(EXIT_SUCCESS);
    }
    
    • 尽可能避免使用setjmp()函数和longjmp()函数

    6.9、总结

    6.10、练习

    最后

    • 2021-01-21看了点书,晚上运行了会代码。
  • 相关阅读:
    http 各个状态返回值
    【转载】关于HttpClient 接口方法总结
    httpclient httpcore jar包及源码
    commons.httpclient-3.X.jar 和 httpclient-4.x.jar是个什么关系?
    【转载】深入浅出REST
    httpclient 用户名密码认证实例
    java发送http请求,内容为xml格式&&传统URI类请求
    RESTful Java client with Apache HttpClient / URL /Jersey client
    MySQL命令行--导入导出数据库
    为什么有时候 php 没有写闭合标签结束符?
  • 原文地址:https://www.cnblogs.com/fewolflion/p/14311130.html
Copyright © 2020-2023  润新知