名词解释:进程概念

一 进程简介

  • 进程诞生的背景
            早期计算机硬件设计简单,功能单一,软件设计非常简单:形如一个while循环结合中断处理
            我们都知道现代的智能手机有很多功能,听音乐,看大片,打电话,浏览器上网,照相等等,然而这样强大的功能在上世纪早期简直是不可想象的(硬件设计或者软件设计)。早期的硬件产品几乎是一个产品仅仅实现了手机的一个特定功能
            伴随着大规模集成电路的发展,以及CPU处理速度越来越快,一个硬件产品可以集成多种单一功能,软件迫切需要一种方案将不同功能的硬件/软件隔离开:也就是一个进程负责管理一部分硬件,彼此分工合作

  • 进程解决的问题
    支持越来越复杂的硬件产品
    CPU 速度越来越快,多个进程共享一个CPU,提高CPU的利用率
    进程占有的资源互不干扰,软件设计清晰,安全有保障

  • 缺陷
    进程模型需要处理器的支持,也就意味着处理器设计更加复杂;同时需要软件设计人员设计操作系统,支持进程模型,操作系统会占用计算机一定的磁盘或者内存资源
    直到今天,大家熟知的Windows操作系统可能占用至少500MB,甚至GB的内存

  • 现代操作系统提供的进程模型
    实时操作系统(RTOS) :适用于时间敏感和任务执行顺序敏感的应用领域,VxWorks和uCOS操作系统就属于这一列
    非实时操作系统:适用于服务器,个人计算机的应用领域,常见的有Windows操作系统,UNIX/Linux操作系统等

1 进程入口

程序员习惯编写如下的代码,main 函数代表进程入口;进程顺序执行直到从main函数返回,进程结束

#include <iostream>
using namespace std;

int main(void)
{
	cout << "Hello World" << endl;
	return 0;
}

2 进程出口

正常终止的五种类型

  • 从main返回
    从main返回的过程可能是 exit(main(int argc, char *argv[])) ,实际上会是exit完成进程终止的工作,参见exit
    ———————————————————————————————————
    调用exit函数:ISO C库函数
    其一、执行所有使用at_exit, on_exit 注册过的函数;
    其二、完成stdio stream缓冲的刷新工作,并关闭所有打开的文件流;
    其三、删除使用tmpfile函数创建的临时文件
#include <iostream>
using namespace std;
/*
void exit(int status); 
int atexit(void (*function)(void));
int on_exit(void (*function)(int , void *), void *arg);
*/
#include <cstdlib>


/*
FILE *tmpfile(void);
*/
#include <cstdio>

void fool(void)
{
	cout << "This is atexit function" << endl;
}

void bar(int stat,void* arg)
{
	cout << "This is on_exit function,exit stat = " << stat << " arg = "<< *((int*)arg) << endl;
}

static int arg = 99;

int main(void)
{
	atexit(fool);
	on_exit(bar,&arg);
	cout << "Hello World" << endl;
	return 0;
}

———————————————————————————————————
调用_exit / _Exit
_Exit 是ISO C库,_exit 是Unix C标准库,两者功能一致
进程立即终止,所有的子进程会被init进程收养,同时父进程会受到SIGCHILD信号
———————————————————————————————————
最后一个线程从例程返回
一个进程可以拥有多个异步的线程,每一个进程都可以代表这个进程的出于生存状态,当最后一个线程退出意味着进程资源可以销毁
———————————————————————————————————
最后一个线程调用pthread_exit
原理同上
———————————————————————————————————
异常终止的三种类型
调用abort
接到一个信号并终止
最后一个线程对取消请求作出响应

二 进程环境

1 环境表

        环境表是一个指针数组,每一个指针表示一个字符串:格式为Env=name字符串格式
在这里插入图片描述

  • environ:环境指针是一个静态链接的全局变量(链接时增加进去的一段目标程序)
  • 环境表:操作系统在初始化进程时,环境表位于用户栈的顶部(增加环境变量一般会造成环境表在堆中分配内存)
  • 环境字符串:可能位于栈中,可能位于静态区,也可能位于堆中

2 环境变量

2.1 输出进程所有环境变量

/*自己写一个 printenv*/
#include <iostream>
using namespace std;
extern "C"
{
	extern char **environ;
}
#include <cstdio>

int my_printenv(void)
{
	char *pstr = NULL;
	if(environ == NULL)
	return -1;
	else
	{
		for(pstr=*environ;(pstr!=NULL);environ++)
		{
			pstr= *environ;
			cout << pstr << endl;
		}
	}
}
int main(void)
{
	
	my_printenv();
	cout << "Hello World" << endl;
	return 0;
}

2.2 获取特定环境变量

#include <iostream>
using namespace std;

/* char *getenv(const char *name);*/
#include <cstdlib>


int main(void)
{
	cout << "environ = " << environ << endl;
	
	if(char * tmp = getenv("HOME"))
	{
		cout << tmp << endl;
	}
	return 0;
}

2.3 修改/删除/增加 进程环境变量

#include <iostream>
using namespace std;

extern "C"
{
	extern char **environ;
}

/* char *getenv(const char *name);*/
/* int setenv(const char *name, const char *value, int overwrite);*/
/* int unsetenv(const char *name);*/
/* int putenv(char *string);*/
#include <cstdlib>

int my_printenv(void)
{
	char *pstr = NULL;
	if(environ == NULL)
	return -1;
	else
	{
		for(pstr=*environ;(pstr!=NULL);environ++)
		{
			pstr= *environ;
			cout << pstr << endl;
		}
	}

	return 0;
}
void print_XDG(void)
{
	if(char * tmp = getenv("XDG_VTNR"))
	{
		cout << tmp << endl;
	}
}

int main(void)
{
	cout << "environ = " << environ << endl;

	/*change: environ指针不变*/
	setenv("XDG_VTNR","8",true);
	print_XDG();
	cout << "environ = " << environ << endl;
	
	/*delete: environ指针不变*/
	unsetenv("XDG_VTNR");
	cout << "environ = " << environ << endl;
	print_XDG();
	
	//my_printenv();

	/*add:environ 指针指向一个heap地址*/
	setenv("XDG_VTNR","9",true);
	print_XDG();
	cout << "environ = " << environ << endl;
	
	/*putenv和setenv的区别在于,setenv会给字符串分配空间*/
	return 0;
}

2.4 setenv 和 putenv 区别

  • putenv缺陷 ,不能使用临时字符串作为参数
  • setenv缺陷,无条件分配字符串内存,效率相对低
/*
setenv 无条件分配新的字符串内存
putenv 从不分配字符串内存
*/
#include <iostream>
using namespace std;

extern "C"
{
	extern char **environ;
}

/* char *getenv(const char *name);*/
/* int setenv(const char *name, const char *value, int overwrite);*/
/* int unsetenv(const char *name);*/
/* int putenv(char *string);*/
#include <cstdlib>

void print_Name(void)
{
	if(char * tmp = getenv("Myname"))
	{
		cout << tmp << " &arr[0] = " << (int*)(tmp)<<endl;
	}
}

char  *val = "Myname=YanJianlei";

int main(void)
{
	cout << "environ = " << environ << endl;
	putenv(val); /*putenv 把常量字符串添加到环境表中*/
	print_Name();
	setenv("Myname","OK?",true); /*setenv 重新分配字符串内存*/
	print_Name();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值