当前位置: 首页 > news >正文

学习嵌入式第二十八天

文章目录

  • 进程和线程
    • 1.进程
      • 1.基本概念
      • 2.进程的创建
      • 3.进程相关的函数接口
      • 4.进程消亡
  • 习题

进程和线程

1.进程

1.基本概念

  • 程序:存放在外存中的一段数据的集合
  • 进程:是程序动态执行的过程,包括创建,调度和消亡

2.进程的创建

  1. 进程空间的分布

    • 每个进程运行起来后,操作系统开辟0 - 4G的虚拟内存空间
    • 进程空间:用户空间+内核空间(不允许用户访问)
    • 用户空间:文本段(文本区)+数据段(数据区)+系统数据段(堆区、栈区)
    • 文本段:存放代码和指令
    • 数据段:字符串常量、已初始化全局变量/静态变量、未初始化全局变量/静态变量
    • 数据区存放数据特点:
      • 未经初始化值为0值
      • 编译时开辟空间
      • 程序结束时回收空间
    • 系统数据段:堆区(malloc空间)、栈区(局部变量、函数运行)
    • 堆区存放数据特点:
      • malloc申请堆区空间
    • 栈区存放数据特点:
      • 未经初始化值为随机值
      • 执行到变量定义开辟内存空间
      • 超过变量作用域回收变量空间
  2. 虚拟地址和物理地址

    1. 虚拟地址
      • 所有能被用户看到的地址均为虚拟地址均为虚拟地址,表示用户可以寻址的范围
    2. 物理地址
      • 内存存放数据对应的实际硬件物理地址
    3. MMU
      • 实际地址和物理地址之间的映射由内存映射单元(MMU)完成
  3. 多进程存储

    • 存储方式

      • 多个进程空间在操作系统中存储时,空间是独立的(物理地址是独立的)

      • 多个进程在操作系统中共用同一个虚拟内存空间(虚拟地址是共享的)

  4. 多进程的调度

    1. 常见的进程调度算法
      1. 先来先执行,后来后执行
      2. 高优先级调度算法
      3. 时间片轮转调度算法
      4. 多级队列反馈调度算法
      5. 负载均衡调度算法
    2. 多进程调度的本质
      • 宏观并行,微观串行
  5. 进程相关命令

    1. top

      示例:top
      功能:根据CPU占用率和内存占用率查看当前所有进程的信息PID:唯一区分进程的ID号
      USER:创建者
      PR/NI:优先级
      VIRT/RES/SHR:资源占用
      S:状态
      %CPU:CPU占用率
      %MEM:内存占用率
      TIME+:运行时长
      COMMAND:进程命令
      
    2. ps -ef

      示例:ps -ef
      功能:查看该时刻所有进程信息UID:创建进程用户
      PID:进程的ID号
      TIME/CMDps -ef | grep 进程名
      查找与进程名对应的进程信息
      
    3. ps -aux

      示例:ps -aux功能:查看该时刻所有进程的信息USER:创建者
      PID:进程的ID号
      %CPU:CPU占用率
      %MEM:内存占用率 
      VSZ 
      RSS 
      TTY      
      STAT:进程的状态 
      START   
      TIME 
      COMMAND
      
    4. 后台执行进程任务

      示例:./a.out &
      功能:后台执行a.out进程
      
    5. jobs

      示例:jobs
      功能:查看终端下所有后台进程任务
      
    6. fg

      示例:fg 编号(通过jobs查看)
      功能:后台执行的任务被放到前台执行
      
    7. nice/renice

      示例:nice -n 优先级编号 进程名renice -n 优先级编号 进程PID
      功能:改变进程的优先级优先级范围:-20~20
      数字越小优先级越高
      
    8. kill/killall

      示例:kill -编号 进程PIDkillall -编号 进程名功能:杀死进程
      
  6. 进程的状态

    进程状态标识含义
    就绪态/运行态R进程位于CPU任务调度的队列中
    可唤醒等待态S等待某个资源的到来,资源到来后被唤醒加入调度队列,等待过程可被打断
    不可唤醒等待态D等待某个资源的到来,资源到来后被唤醒加入调度队列,等待过程不可被打断
    停止态T用户人为让进程任务暂停等待
    僵尸态Z进程代码运行结束,空间尚未回收
    结束态X进程代码运行结束,空间被回收

3.进程相关的函数接口

  1. fork

    原型:pid_t fork(void);
    功能:创建一个新的进程,新的进程称为子进程,调用fork的进程称为父进程
    参数:缺省
    返回值:父进程中返回子进程的PID子进程中返回0出错返回-1
    
    • 子进程拷贝父进程文本段、数据段、系统数据段
    • 父进程与子进程空间独立,同一份代码中的个变量和数据都会在父子进程中各有一份,父子进程修改自己空间的数据不会影响对方
    • 进程的PID不一样
    • fork的返回值不一样
    • PID > 0
  2. getpid和getppid

    原型:pid_t getpid(void);
    功能:获得调用函数进程的PID号原型:pid_t getppid(void);
    功能:获得调用函数父进程的PID号
    
  3. exit和_exit

    原型:void exit(int status);
    功能:结束进程任务并返回进程结束状态
    参数:status:进程结束的状态值原型:void _exit(int status);
    功能:结束进程任务并返回进程结束状态
    参数:status:进程结束的状态值
    返回值:
    
    • 在主程序中调用和return功能一致
    • return在函数内部将结束该函数
    • exit在函数中会结束该进程
    • exit会在结束前刷新缓存区
    • _exit不会刷新缓存区
  4. wait

    原型:pid_t wait(int *wstatus)
    功能:回收子进程空间
    参数:wstatus:存放子进程结束空间的首地址
    返回值:成功返回回收到的子进程的PID失败返回-1
    
    • wait具有阻塞等待功能,等到有子进程结束才会回收子进程继续向下执行

4.进程消亡

  1. 孤儿进程
    • 父进程先结束,子进程会变成孤儿进程,被init进程收养
  2. 僵尸进程
    • 每个进程结束必然会经历的阶段
    • 产生原因:子进程结束后,父进程没有回收子进程空间,导致进程执行结束,空间依然被占用的状态。
    • 避免产生僵尸进程
      • 父进程先结束,子进程会成为孤儿进程,孤儿进程被init进程收养,子进程再结束,init进程回收进程空间
      • 子进程结束,父进程回收子进程空间,

习题

编写一个程序,将当前系统中所有进程的PID、PPID、Name信息记录到record.txt文件中

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<dirent.h>
#include<math.h>
#include<time.h>
#include<sys/wait.h>int get_allnumdir(struct dirent *pp){char *pstr = NULL;pstr = pp->d_name;while(pstr != NULL && *pstr != '\0'){if(*pstr < '0' || *pstr > '9'){return -1;}pstr++;}return 1;
}
void get_information(FILE *fp1,char *name,char *pid,char *ppid){char buff[100] = {0};char *str = NULL;rewind(fp1);while(fgets(buff,sizeof(buff),fp1) != NULL){str = strtok(buff,"\t");if(0 == strcmp(str,"Name:")){str = strtok(NULL,"\n");strcpy(name,str);}else if(0 == strcmp(str,"Pid:")){str = strtok(NULL,"\n");strcpy(pid,str);}else if(0 == strcmp(str,"PPid:")){str = strtok(NULL,"\n");strcpy(ppid,str);}   }
}int main(void){FILE *fp = NULL;FILE *fp1 = NULL;DIR *dir = NULL;struct dirent *pp = NULL;char tmpbuff[4096] = {0};char ppid[10] = {0};char pid[10] = {0};char name[100] = {0};fp = fopen("record.txt","w");if(NULL == fp){perror("fail to fopen");return -1;}dir = opendir("/proc");if(NULL == dir){perror("fail to opendir");return -1;}while(1){tmpbuff[0] = '\0';memset(name, 0, sizeof(name));memset(pid, 0, sizeof(pid));memset(ppid, 0, sizeof(ppid));pp = readdir(dir);if(NULL == pp)break;if(get_allnumdir(pp) == 1){sprintf(tmpbuff,"/proc/%s/status",pp->d_name);fp1 = fopen(tmpbuff,"r");if(NULL == fp1){continue;}get_information(fp1,name,pid,ppid);fprintf(fp,"Name: %s\n",name);fprintf(fp,"PID: %s\n",pid);fprintf(fp,"PPID: %s\n",ppid);fclose(fp1);}}closedir(dir);fclose(fp);return 0;
}
http://www.lryc.cn/news/620940.html

相关文章:

  • python爬虫学习(2)
  • 大模型微调方法讲解
  • linux 软硬链接详解
  • 服务器数据恢复—误删服务器卷数据的数据恢复案例
  • ESXI 6.7服务器时间错乱问题
  • QT+Yolov8 推理部署,ONNX模型 ,实例分割+目标检测
  • 【会员专享数据】2000-2024年我国乡镇的逐日PM₁₀数据(Shp/Excel格式)
  • 6、C 语言指针初阶知识点总结
  • AI搜索优化专家孟庆涛:以技术温度重构“人机信息对话”新范式
  • 前端Vite介绍(现代化前端构建工具,由尤雨溪开发,旨在显著提升开发体验和构建效率)ES模块(ESM)、与传统Webpack对比、Rollup打包
  • 飞算JavaAI合并项目实战:7天完成3年遗留系统重构
  • 92、23种设计模式-单例模式
  • LeetCode 面试经典 150_数组/字符串_最后一个单词的长度(19_58_C++_简单)(反向遍历)
  • vector 认识及使用
  • MTK平台Wi-Fi学习--如何修改wifi 的TX Power
  • 计算机毕设大数据选题推荐 基于spark+Hadoop+python的贵州茅台股票数据分析系统【源码+文档+调试】
  • STL——容器——容器适配器
  • Mac chrome浏览器下载DevEco Studio 6.0.0 Beta2失败
  • MacOS 系统计算机专业好用工具安装
  • Spring Boot 深度解析:从原理到实践
  • 亚马逊手工制品分类体系革新:从流量重构到运营升级的深度解析
  • [已解决]当启动 Spring Boot 应用时出现 Using generated security password xxx提示
  • Rust Web框架Axum学习指南之入门初体验
  • vue部署正式环境上传nginx后遇到的问题
  • MySQL中的DML(二)
  • mysql查询中的filesort是指什么
  • 第三方软件检测:软件性能测试报告(一)
  • CMake笔记:Alias Target在哪些地方可以使用
  • 使用Docker安装MeiliSearch搜索引擎
  • 【完整源码+数据集+部署教程】柠檬质量检测系统源码和数据集:改进yolo11-DBBNCSPELAN