商城网站的主要模块,什么网站可以免费做宣传,网站建设费用怎么核算,简单的crm客户管理系统✨个人主页#xff1a; 熬夜学编程的小林 
#x1f497;系列专栏#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 
目录 1、进程优先级 
2.1、什么是优先级 
2.2、优先级的描述 
2.3、优先级与权限的关系 
2.4、为什么要有优先级 
2.5、Linux优先级的…✨个人主页 熬夜学编程的小林 
系列专栏 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 
目录 1、进程优先级 
2.1、什么是优先级 
2.2、优先级的描述 
2.3、优先级与权限的关系 
2.4、为什么要有优先级 
2.5、Linux优先级的特点 
2.6、其他概念 
2、命令行参数 
3、环境变量 
3.1、基本概念 
3.2、PATH环境变量 
3.3、其他环境变量 1、进程优先级 
2.1、什么是优先级 指定进程获取某种资源(CPU)的先后顺序。 2.2、优先级的描述 进程优先级的描述跟进程状态描述类似实质是在task_struct(内存控制块)结构体内部有一个描述优先级的属性通过数字表示先后顺序。Linux 中优先级数字越小优先级越高。 2.3、优先级与权限的关系 权限决定能不能获取资源。 优先级决定获取资源的顺序已经能获取资源。 2.4、为什么要有优先级 进程访问的资源(CPU)始终是有限的。系统中进程大部分情况都是比较多的。 操作系统关于调度和优先级的原则分时操作系统基于时间片进行调度保证基本的公平。如果进程因为长时间不被调度就造成了饥饿问题。 2.5、Linux优先级的特点 
在讲解优先级特点之前我们先通过一个C语言程序查看优先级。 
C语言代码 
#includestdio.h
#includeunistd.hint main()
{while(1){printf(I am a process,pid:%d\n,getpid());}return 0;
} 命令行代码 
ps -al // 查看所有进程信息 
测试结果  
我们很容易注意到其中的几个重要信息有下 UID : 代表执行者的身份。 PID : 代表这个进程的代号。 PPID 代表这个进程是由哪个进程发展衍生而来的亦即父进程的代号。 PRI 代表这个进程可被执行的优先级其值越小越早被执行。 NI 代表这个进程优先级的修正数据nice值新的优先级  默认优先级  nice达到对于进程优先级动态修改的过程。 调整优先级 nice/renice 调整优先级 此处博主使用top命令调整优先级。 输入top命令进入top后按“r”–输入进程PID–输入nice值 测试一  
我们将nice值改为100现象如下 可以看到 NI 只修改为了19PRI修改为了99。表名nice值并不能任意调整而是有范围的。 范围是 [-20,19] 共40个数字。 测试二 
我们将nice值改为-10现象如下 我们可以看到当我们第二次修改nice值时不允许我们修改因为修改优先级是有风险的如果强制需要修改nice值我们只需要切换成root账号即可。  测试三 
使用root账号将nice值改为-10现象如下 我们可以看到NI修改成了-10PRI修改成了70我们刚刚的PRI是99将nice值修改为-10为什么现在的PRI为70了呢原因是 每次调整优先级都是从80开始的。新的优先级  默认优先级  nice70  80 - 10。 测试四 
使用root账号将nice值改为-100现象如下 可以看到NI被修改为-20因此能够证明nice的最小值为-20且新的优先级  默认优先级  nice60  80 - 20。 2.6、其他概念 竞争性: 系统进程数目众多而CPU资源只有少量甚至1个所以进程之间是具有竞争属性的。为了高效完成任务更合理竞争相关资源便具有了优先级。独立性: 多进程运行需要独享各种资源多进程运行期间互不干扰。并行: 多个进程在多个CPU下分别同时进行运行这称之为并行。并发: 多个进程在一个CPU下采用进程切换的方式在一段时间之内让多个进程都得以推进称之为并发。 
2、命令行参数 
写C语言代码中main函数也是函数可以带参数 答案是可以带参数也可以不带参数下面就使用带参数的main函数演示。 代码演示 
#includestdio.h// 命令行参数测试
int main(int argc,char* argv[])
{int i  0;for(i0;iargc;i){printf(argv[%d]  %s\n,i,argv[i]);}return 0;
}测试结果 通过上图现象我们可以看到argc是元素个数argv是一个边长数组猜测数组以NULL结尾。  验证数组以NULL结尾 
#includestdio.hint main(int argc,char* argv[])
{int i  0;// argv[i]为假则循环结束for(i0;argv[i];i){printf(argv[%d]  %s\n,i,argv[i]);}return 0;
} 
测试结果  为什么要有命令行参数 本质命令行参数本质是交给我们程序的不同选项用来定制不同的程序功能。命令中会携带很多选项。 命令行中启动的程序是谁干的 命令行中启动的程序都会变成进程且都是bash的子进程因此是bash(命令行解释器)干的。 代码演示一 
#includestdio.h
#includeunistd.hint g_val  10000;
int main()
{printf(I am parent process,g_val:%d,pid:%d,ppid:%d\n,g_val,getpid(),getppid());sleep(5);pid_t id  fork();if(id  0){while(1){printf(I am child process,g_val:%d,pid:%d,ppid:%d\n,g_val,getpid(),getppid());sleep(1);}}else{printf(I am parent process,g_val:%d,pid:%d,ppid:%d\n,g_val,getpid(),getppid());sleep(1);}return 0;
} 父进程的数据默认能被子进程看到并访问。 代码演示二 
#includestdio.h
#includeunistd.h
#includestring.hint g_val  10000;
int main(int argc,char* argv[])
{printf(I am parent process,g_val:%d,pid:%d,ppid:%d\n,g_val,getpid(),getppid());if(argc ! 2){printf(Usage: %s -[a,b,c,d]\n, argv[0]);return 1;}if(strcmp(argv[1], -a)  0){printf(this is function1\n);}else if(strcmp(argv[1], -b)  0){printf(this is function2\n);}else if(strcmp(argv[1], -c)  0){printf(this is function3\n);}else if(strcmp(argv[1], -d)  0){printf(this is function4\n);}else{printf(no this function!!\n);}return 0;
} 
测试结果  命令行中启动的程序都会变成进程且都是bash的子进程。启动程序默认是输入给父进程bash(命令行解释器)的 3、环境变量 
3.1、基本概念 
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。如我们在编写C/C代码的时候在链接的时候从来不知道我们的所链接的动态静态库在哪里但是照样可以链接成功生成可执行程序原因就是有相关环境变量帮助编译器进行查找。环境变量通常具有某些特殊用途还有在系统当中通常具有全局特性。 
3.2、PATH环境变量 
基本认知 执行命令和运行自己写的程序是没有区别的且Linux中70% 的命令是C语言写的。 为什么执行ls这些系统提供的命令可以不带路径而我们自己写的C语言程序需要加./(带路径)呢 Linux系统重存在一些全局的设置表明告诉命令行解释器应该去哪个路径下去寻找可执行程序当执行ls命令(可执行程序在/usr/bin目录中)时会先去找ls对应的可执行程序默认去PATH中找。 查看PATH内容  通过echo $PATH 获取PATH(环境变量)内容 类似*p。 补充 系统中很多的配置在我们登录Linux系统的时候已经被加载到了bash进程中(内存)。bash在执行命令的时候需要先找到路径(默认去PATH中找)因为未来要加载。 如果我们想像系统指令一样执行自己写的可执行程序怎么做 
方式一(粗暴)直接将我们的可执行程序拷贝到PATH的其中一个路径(例如/usr/bin)中。 
注意拷贝内容到PATH环境中需要配root权限此处使用sudo提权。 
sudo cp myprocess /usr/bin  # 此处的/usr/bin也可以是PATH中的其他路径 不建议使用这种方式因此下面我们将该可执行程序在/usr/bin中的内容删除。 
sudo rm /usr/bin/myprocess 方式二(温柔)把可执行程序路径增加到PATH环境变量中。 
错误示范 
PATH/home/jkl/path # 将可执行程序的当前目录赋值给PATH变量会直接覆盖PATH 环境变量直接被我们新的路径覆盖了怎么办呢 其实很简单直接将系统关闭重进系统就可以了。因为我们上面说了 系统中很多的配置在我们登录Linux系统的时候已经被加载到了bash进程中(内存)。 我们重新登录系统之后发现环境变量回来了且不能直接执行我们写的可执行程序了。 正确示范 
PATH$PATH:/home/jkl/path # 将原本的PATH路径以及我们可执行程序当前目录赋值给PATH 演示结果 PATH环境变量是Linux系统中搜索可执行程序的默认路径也是which指令搜索路径的默认路径。 PATH环境变量的路径是内存级别的重新登录系统又会变成默认路径怎样让追加的环境变量路径永久存在呢 最开始的环境变量不是在内存中而是在系统对应的配置文件中在我们登录系统时会创建一个bash进程bash进程会读取配置文件然后把配置文件的环境变量(包括PATH)在自己的bash进程拷贝一份。 这个配置文件在哪里 
vim .bash_profile
vim .bashrc
vim /etc/bashrc 
我们的PATH配置文件可能在.bash_profile或者.bashrc中。博主的在.bashrc中。 想要登录时每次都默认执行自己写的可执行程序把可执行程序路径加到环境变量的配置文件里面即可如下图 加上该路径之后myprocess可以像系统命令(ls)一样在任意目录中使用了且无需加./。  Windows也有环境变量我们在安装jdk或者python时一般需要配置环境变量。 3.3、其他环境变量 
env : 查看系统所有的环境变量 history 查看历史命令 HOME : 家目录所在的环境变量 PWD : 当前目录路径变化 SHELL :  当前Shell,它的值通常是/bin/bash。 HISTSIZE : 历史命令个数 上翻下翻 Linux默认会记录最新的1000条命令 自己定义一个环境变量 export THIS_IS_MY_ENVhellolinux   导入环境变量(不加export依旧存在变量本地变量) unset THIS_IS_MY_ENV  取消环境变量 export测试 疑问export 也是一个命令命令就会创建子进程子进程就应该不被bash看到为什么却能将变量导入到环境变量中。 80% 命令都是bash创建子进程执行的 称为普通命令。还有20%命令如(export / echo) 由bash亲自执行的称为内建命令。 怎么证明真的有内建命令呢 通过上面实验我们可以证明确实有内建命令。  普通测试  本地变量只在bash内部有效无法被子进程继承下去。导成环境变量才能被获取。用本地变量理解内建命令。内建命令可以查到本地变量。echo能够打印本地变量(子进程无法获取)也能够证明echo是内建命令。 注意已经存在的本地变量导成环境变量只需要使用export 变量名即可。 
能否通过C语言程序查看环境变量呢 答案是可以的在写程序之前我们需要查一下手册man environenviron为查看全局的指针变量。 C语言程序 
#includestdio.h
#includeunistd.h
int main()
{extern char** environ;// 声明外部文件变量int i0;for(i0;environ[i];i)// environ[i]为假则循环结束{printf(env[%d]-%s\n,i,environ[i]);}return 0;
}测试结果  测试结果与使用命令env的结果是一样的。 说明环境变量默认也是可以被bash子进程拿到的。环境变量们默认在bash内部。 环境变量有很多bash内部是如何组织的 通过上面的C语言代码我们大概可以推断环境变量的组织与命令行参数类似是通过一个变长数组组织的最后一个数据以NULL结尾。 main函数带参的C语言程序 
#includestdio.h
#includeunistd.h
int main(int argc,char* argv[],char* env[])
{int i  0;for(i0;env[i];i){printf(env[%d]-%s\n,i,env[i]);}return 0;
}测试结果  bash进程启动的时候默认会给子进程形成argv[]命令行参数表(用户输入的命令行来)env[]环境变量表(从OS的配置文件来)bash通过各种方式交给子进程。 补充 
导环境变量的本质把字符串添加到环境变量表中。环境变量具有系统级的全局属性因为环境变量会被子进程继承下去。 
获取环境变量方法 
extern char** environ;main函数参数getenv(path); 
man getenv 代码  
#includestdio.h
#includeunistd.h
#includestdlib.h
int main(int argc,char* argv[],char* env[])
{char* path  getenv(PATH);if(path  NULL) return 1;printf(psth:%s\n,path);return 0;
}测试结果  putenv(); // 创建环境变量