Linux系统【一】CPU+MMU+fork函数创建进程
切板中的内容输出到文件### 进程相关概念
程序:编译好的二进制文件,在磁盘上,不占用系统资源(不包括磁盘)。(剧本)
进程:占用系统资源,是程序的一次运行。(戏剧)
一个程序可以产生多个进程,一个进程可以调用多个程序
并发:并行执行
单道程序设计:DOS系统
多道程序设计:时钟中断
中央处理器CPU
存储介质:按照容量从大到小:
硬盘->内存->cache(高速缓存)->寄存器
预取器:从cache中取出指令
译码器:解析指令
算数逻辑单元(ALU):只会+
和<<
寄存器堆:ALU操作的寄存器扎堆的地方
然后再将寄存器中的值返回给cache
MMU
MMU位于CPU内部:负责虚拟内存和物理内存之间的映射,设置修改内存访问的级别(CPU中设置了0-3四个等级,Linux系统中用到0级内核区和3级用户区)
每产生一个进程产生一个虚拟内存:可用的地址空间
每次最小分配物理内存4K(一个page)
同一个程序的不同进程的kernel区内存映射到同一个空间,但是使用的是不同的PCB
PCB
处于kernel区,进程描述符\进程控制块,实际上是一个task_struct
结构体,里面有很多的成员
- 进程的id,无符号整数
- 进程状态:初状态、就绪状态、运行状态、挂起状态、终止状态
- 进程切换时候需要保存和恢复的一些寄存器
- 描述虚拟地址空间的信息
- 描述控制终端的信息
- 当前进程的工作目录
umask
掩码- 文件描述符表
- 和信号相关的信息
- 用户id和组id
- 会话和进程组
- 进程可以使用的资源上限
ulimit -a
环境变量
Linux系统是多用户多任务的开源操作系统
用户操作计算机的时候运行的一些信息通过环境变量进行设置
- 字符串
char * environ[]
,存储在用户区,高于stack
的起始位置 - 统一的存储格式:
名字=值[:值]
- 值用来描述进程环境信息
以shell
为例,所使用的环境变量为PATH
,在解析命令的时候按照PATH
中的内容从前往后逐个目录进行查找,因此如果希望使用新版本软件应该把新版本软件的环境变量向前移动
SHELL 所使用的命令解析器在哪里
HOME 家目录在哪里
LANG 使用的是什么语言
TERM 所使用的终端类型,图形界面所使用的一般是xterm,可以显示汉字,字符界面一般不可以
通过程序打印所有的环境变量:
#include<stdio.h>extern char ** environ;//引入环境变量表int main(void)
{int i;for(int i=0;environ[i]!=NULL;++i){printf("%s\n",environ[i]);}return 0;
}
相关函数
getenv
手册第三章setenv
unsetenv
删除环境变量:即使没有那个环境变量也会返回成功,只有当参数为已经有的环境变量的非法格式例如:name=
才会报错,例如:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{const char* name="123ABC";char *val;setenv(name,"123",1);printf("%d\n",unsetenv("123ABC=1")); //-1printf("%d\n",unsetenv("123ABC")); //0return 0;
}
进程控制
创建进程的方法:
- 运行可执行程序
- 通过
fork
函数创建子进程
fork函数创建子进程
#include<unistd.h>
pid_t fork(void)
fork
有两个成功返回值
如果子进程创建失败则返回-1,并且将错误信息保存在erron中,我们可以使用perror输出错误信息。
如果子进程创建成功则会在父进程中返回子进程的ID,在子进程中返回0
父进程的fork
返回子进程ID,子进程的fork
返回值为0,通过对返回值的判断处于哪个进程
可执行文件的父进程是bash
创建单个进程
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main()
{printf("begin:\n");pid_t pid = fork();if(-1 == pid){perror("process creat:");exit(1);}else if(0 == pid){printf("This is son process,pid = %d \n",(int)getpid());printf("My father process pid = %d \n",(int)getppid());}else{printf("This is father process,pid = %d \n",(int)getpid());printf("My father process pid = %d \n",(int)getppid());sleep(1);}printf("end\n");return 0;
}
循环创建N个子进程
如果直接使用循环进行创建,则n层循环会创建2n-1个子进程,这显然不是我们需要的。
因此我们需要在子进程中直接跳出循环,这样就不会产生过多的子进程
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>int main(int argc,char* argv[])
{if(argc<2){printf("too few arguments\n");exit(1);}if(argc>2){printf("too few arguments\n");exit(1);}int i,limit=argv[1][0]-'0';printf("begin:\n");for(i=0;i<limit;++i){pid_t pid = fork();if(-1 == pid){perror("process creat:");exit(1);}else if(0 == pid){printf("This is %dth son process,pid = %d \n",i+1,(int)getpid());printf("My father process pid = %d \n",(int)getppid());break;}
}printf("end\n");return 0;
}
在《APUE》中说到如果不加控制的话父进程有98%的可能性获得CPU的控制权(不过我的电脑上并不是这样),由内核的调度算法决定
getuid
获取当前进程实际用户IDuid_t getuid(void);
获取当前进程有效用户IDuid_t geteuid(void);
getgid
获取当前进程实际用户组IDgid_t getgid(void);
获取当前进程有效用户组IDgid_t getegid(void);
进程共享
父子进程相同的:全局变量、.data,.text,栈、共享库、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式都是相同的
父子进程对于前面的变量的处理:读时共享写时复制
如果子进程只对前面的数据进行读取,则和父进程共享同一个变量,如果对前面的数据进行修改(写,改变),则复制一份新的,指针的话会制定一个新的地址。
父子进程不同的:进程ID,fork返回值,父进程ID,进程运行时间,闹钟(定时器),未决信号集
进程运行时间:子进程的运行时间为父进程fork()调用时间
父子进程共享:
- 文件描述符
mmap
建立的映射区(进程间的通信)
我自己写了一个测试程序
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>int main(int argc,char* argv[])
{int fd=open("test",O_CREAT | O_RDWR | O_TRUNC,0644);pid_t fid=getppid();if(argc<2){printf("too few arguments\n");exit(1);}if(argc>2){printf("too few arguments\n");exit(1);}int i,limit=argv[1][0]-'0';printf("begin:\n");for(i=0;i<limit;++i){pid_t pid = fork();if(-1 == pid){perror("process creat:");exit(1);}else if(0 == pid){break;}}char buffer[100];memset(buffer,0,sizeof(buffer));int sz=sprintf(buffer,"This is %dth son process,pid = %d \n",i+1,(int)getpid());write(fd,buffer,sz);if(getppid()==fid){close(fd);printf("end\n");}return 0;
}
gdb调试
使用gdb调试的时候,gdb只能跟踪一个进程,可以在fork函数调用之前,通过执行设置gdb调试工具跟踪父进程或者是跟踪子进程,默认跟踪父进程。
set follow-fork-mode child
命令设置gdb在fork之后跟踪子进程set follow-fork-mod parent
设置跟踪父进程- 注意一定在
fork
函数调用前设置才有效
Linux系统【一】CPU+MMU+fork函数创建进程相关推荐
- 理解进程、通过调用 fork 函数创建进程
文章目录 1.理解进程 1.1 CPU核的个数与进程数 1.2 进程 ID 2.通过调用 fork 函数创建进程 1.理解进程 进程(Process),其定义如下:"占用内存空间的正在运行的 ...
- linux系统查看CPU使用含义、IO、内存、硬盘使用、负载
一.Linux系统查看CPU使用率命令 在linux的系统维护中,可能需要经常查看cpu使用率,分析系统整体的运行情况.而监控CPU的性能一般包括以下3点:运行队列.CPU使用率和上下文切换. 对于每 ...
- Linux中assert头文件,linux系统下如何使用assert函数
linux系统下如何使用assert函数 只要看得懂程序的人都知道assert,在Windows下使用VC编写,使用assert之后,只需在IDE中设置为debug版或者是release版,编译器就会 ...
- python 监控linux硬盘,Python3监控windows,linux系统的CPU、硬盘、内存使用率和各个端口的开启情况详细代码实例...
由于项目的需要,需要做一个简单监控服务器的CPU利用率.CPU负载.硬盘使用率.内存利用率和服务器的各个端口的开启情况的程序,并把结果通知到监控平台,如果出现异常,监控平台打电话或者发短信通知给具体的 ...
- Linux系统查看CPU
在linux的系统维护中,可能需要经常查看cpu使用率,分析系统整体的运行情况,以便性能分析优化.而监控CPU的性能一般包括以下3点:运行队列.CPU使用率和上下文切换. 对于每一个CPU来说运行队列 ...
- Linux系统的CPU使用率和Load
为什么80%的码农都做不了架构师?>>> 好吧,我承认这个话题是老生常谈,我自己也在2009年刚接触性能测试时就已经开始关注并略知一二:然而,对于CPU使用率和系统负载Load ...
- windows查看linux文件中文,Linux 系统下无法查看Windows 中创建的中文文件名
标 题: Linux 系统下无法查看Windows 中创建的中文文件名 我是Linux初学者,在网上搜索了很久,经过多次尝试仍然无法解决问题,只好在这里发贴请教了,还望各位高手指点一下. 问题描述: ...
- Linux系统获取CPU温度
Linux系统获取CPU温度 摘自:https://jingyan.baidu.com/article/cbf0e500407d072eab289343.html 各位好,本篇将简单介绍如何在不同系列 ...
- linux编译怎么选择cpu,使用cpuminer在Linux系统中用CPU挖矿
所用的Linux系统是Ubuntu 16.04 LTS 64位版本,以下是使用cpuminer在Linux系统中用CPU挖矿的基本步骤. 1.注册账号 先到MinerGate注册账号,然后到这里就可以 ...
最新文章
- 生产者/消费者模型详解(基于Java)
- 图表对比详解:亚马逊、微软和谷歌云的机器学习即服务哪家强
- php数组转字符串 join,jQuery中将数组转换成字符串join()和push()使用
- 使用Github(Github Issues)
- 你的女神今日结婚了!!!你失恋了......
- 用python 写网络爬虫--零基础
- 2.算法通关面试 --- 堆栈和队列
- 工作中用到的sh脚本(持续更新)
- 白话大数据 | 从买菜这件小事来聊聊数据仓库
- 【大数据----Spark】Spark入门教程[3]
- 微信小程序生成海报并保存到本地(附带二维码生成)
- nginx 域名重定向
- java模拟器修改游戏分辨率_海马玩模拟器修改分辨率DPI和隐藏虚拟按键的方法...
- python的深浅拷贝与linux中的软硬链接
- 甘肃地形图之陇右地形分析、DEM数据下载
- Python3-豆瓣电影影片差评和影片封面照片的爬取
- NSNumber 与 Tagged Pointer
- 收藏很久的开关电源书籍
- 機器學習基石 机器学习基石 (Machine Learning Foundations) 作业二 Q19-20 C++实现
- Unity入门:第一个游戏
热门文章
- CTU 2017 J - Punching Power (二分图匹配)
- mysql启动错误排查-无法申请足够内存
- 安装openstack时遇到的错误
- vi @-function
- spring对事务的控制 AOP
- php设计是什么意思,php – 什么是更好的设计?
- ubuntu 14.04 java_Ubuntu14.04下配置Java环境
- 对hash签名失败_vue项目中微信jssdk在ios签名失败
- 微处理器 微型计算机系统,作业答案11微处理器微型计算机和微型计算机系统三者之间.DOC...
- 微型计算机2017年9月上,2017年9月计算机一级考试WPS Office冲刺题