一,进程的优先级
1.cpu分配资源的先后顺序就是优先级
2.优先权高的进程有优先执行的权利,
3.可以让进程运行在指定的cpu上,改善系统整体性能
二,查看进程优先级
1.使用ps-al,可以看进程的优先级

2.PRI和NI
PRi代表当前进程的优先级是多少,数字越小越快被执行,进程的优先级也越高
NI代表nice值,为修正的优先级顺序,
PRI值越小越快被执行,那么加入nice值后,PRI(old)不会改变,默认80,将会使得PRI变为:PRI(new)=PRI(old)+nice
这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
所以,调整进程优先级,在Linux下,就是调整进程nice值
nice其取值范围是-20至19,一共40个级别
三,查看进程优先级的命令
1.用top命令查看并修改nice值
输入top-按r ,输入进程pid,输入nice值。(如果显示拒绝提升的话,使用sudo提升top命令的权限)。
2.其他概念
竞争性:系统数目很多,但只有cpu数量少,甚至只有一个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级。
独立性:多进程运行,需要独享各种资源,所以多进程期间互不干扰。
并行:多个进程在多个cpu中进行,同时进行运行,称为并行。
并发:多个进程在一个cpu上采用进程切换的方式,在一段时间内,让多个进程得以推进,称为并发。
三.环境变量
1.概念
1.1 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
1.2 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在 哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
1.3 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
2.常见环境变量
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell(指令翻译器),它的值通常是/bin/bash。
使用export也可以查看当前环境变量。
查看环境变量方法:echo $NAME //NAME:你的环境变量名称
3.把写的程序变成一个默认指令去运行
在运行程序之前我们都需要带 ./程序名 才能运行程序
而系统默认的 ll ps都不需要,因为在实际执行命令时,会在默认路径下搜索指令
此时我们把我们写的程序加入 usr/bin路径中,就可以不用带 ./

还可以设置新的环境变量实现
export PATH=$PATH:绝对路径

当断开连接以后,就可以看到环境变量会重新配置。
四.发送信息到指定用户
4.1使用wall命令
wall 'this is message'
4.2 使用echo命令
sudo echo "this is message" > /dev/pts/2
4.3 使用write命令
write zyz pts/0 (zyz 用户名称) (pts/0 物理输入设备)
五.main函数的输入输出
5.1.输入输出
#include<stdio.h>
#include<unistd.h>
int main(int argc[],char*argv[],char*envp[])
{
for(int i=0;argv[i]!=NULL;i++)
{
printf("argc[%d],%s\n",i,argv[i]);
sleep(1);
}
return 0;
}
当运行时./test 就会发现会输出一个test(这是因为在运行时,给了一个test的输入)
argv[],是一个环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
当我们多给几个输入时

就可以看到有多个输出。
5.2 获取环境变量
1.命令行第三个参数
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i = 0;
for(; env[i]; i++){
printf("%s\n", env[i]);
}
return 0;
}
2.第三方变量获取
#include <stdio.h>
int main(int argc, char *argv[])
{
extern char **environ;
int i = 0;
for(; environ[i]; i++){
printf("%s\n", environ[i]);
}
return 0;
}

就可以得到当前的环境变量。
5.3 主函数带操作符分流
if(argc == 2){
if(strcmp(argv[1], "-a") == 0){
printf("hello bit\n");
}
else if(strcmp(argv[1], "-b") == 0){
printf("hello world!\n");
}
else{
printf("hello default!\n");
}
}
printf("argc : %d\n", argc);

六.程序地址空间
在学习c的时候,可以看到程序存取的区间如下图所示

printf("code addr: %p\n", main);
char *str= "hello world";
printf("read only addr: %p\n", str);
printf("init addr: %p\n", &g_val);
printf("uninit addr: %p\n",&g_unval);
int *p = malloc(10);
printf("heap addr: %p\n", p);
printf("stack add: %p\n", &str);
printf("stack add: %p\n", &p);

可以看到地址空间向上增长。
进程的独立性的检查
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
int g_val = 100;
int main(int argc, char *argv[], char *envp[])
{
pid_t id = fork();
//int id = fork();
if(id == 0){
//child
printf("child: pid: %d, ppid : %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
}
else{
//father
sleep(2);
printf("father: pid: %d, ppid : %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
}
sleep(1);
}
我们发现,输出出来的变量值和地址是一模一样的,很好理解呀,因为子进程按照父进程为模版,父子并没有对变量进行进行任何修改。可是将代码稍加改动:
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
int g_val = 100;
int main(int argc, char *argv[], char *envp[])
{
pid_t id = fork();
//int id = fork();
if(id == 0){
//child
g_val=200;
printf("child: pid: %d, ppid : %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
}
else{
//father
sleep(2);
printf("father: pid: %d, ppid : %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
}
sleep(1);
}

我们发现,父子进程,输出地址是一致的,但是变量内容不一样!能得出如下结论:
也能充分体现进程的独立性。
1.变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
2.但地址值是一样的,说明,该地址绝对不是物理地址!
3. 在Linux地址下,这种地址叫做虚拟地址
4.我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理
OS必须把虚拟地址转换为实际地址。
进程地址空间图

实际的地址分配。上面的图就足矣说名问题,同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址。只有在写入时才会发生拷贝。
794

被折叠的 条评论
为什么被折叠?



