首页 > 系统相关 >Linux系统编程——进程

Linux系统编程——进程

时间:2024-07-27 11:58:18浏览次数:12  
标签:ps const int 编程 pid char Linux 进程

学习目标:


学习内容:

1.进程的含义?
进程是一个程序执行的过程,会去分配内存资源,cpu的调度

pcb  是一个结构体,process control block  print circuit board
vim -t
task_struct 

PID,进程标识符
当前工作路径   chdir
umask  0002
进程打开的文件列表  文件IO中有提到
信号相关设置 处理异步io,
用户id,组id
进程资源的上限
ulimit -a,显示资源上限。
2.进程和程序的区别?
程序:静态
存储在硬盘中代码,数据的集合
进程:动态
程序执行的过程,包括进程的创建、调度、消亡
.c ----> a.out-----> process(pid)
1)程序是永存,进程是暂时的
2)进程有程序状态的变化,程序没有
3)进程可以并发,程序无并发
4)进程与进程会存在竞争计算机的资源
5)一个程序可以运行多次,变成多个进程
一个进程可以运行一个或多个程序
内存的分布
0-3G,是进程的空间,3G-4G是内核的空间,虚拟地址
虚拟地址 *  物理内存和虚拟内存的地址 映射表 1page=4k    mmu


进程分类:
1、交互式进程
2、批处理进程   shell脚本 
3、 守护进程 


3.进程的作用? 并发,并行区别。
while (1) { while (1) { 上下左右
发视频
} }
4.进程的状态:
3个状态,就绪→执行态→阻塞(等待,睡眠)基本操作系统
linux中的状态,运行态,睡眠态,僵尸,暂停态。

5.进程的调度,进程上下文切换
内核主要功能之一就是完成进程调度, 硬件,bios,io,文件系统,驱动
调度算法, other,idle
rr,fifo
宏观并行
微观串行

6.查询进程相关命令
1.ps aux

查看进程相关信息

1.就绪态、运行态 R
2.睡眠态、等待态
可唤醒等待态 S
不可唤醒等待态 D
3.停止态 T
4.僵尸态 Z
5.结束态

2.top
根据CPU占用率查看进程相关信息

3.kill和killall发送一个信号
kill -2 PID  15
发送信号+PID对应的进程,默认接收者关闭

killall -9 进程名
发送信号 进程名对应的所有进程
killall a.out

原语:
1.fork();
pid_t fork(); 叉子
一次调用,会返回两次。
子进程先运行和是父进程先进程,顺序不确定。
变量不共享。
子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同。
功能:通过该函数可以从当前进程中克隆一个同名新进程。
  克隆的进程称为子进程,原有的进程称为 父进程。
  子进程是父进程的完全拷贝。
  子进程的执行过程是从fork函数之后执行。
  
  子进程与父进程具有相同的代码逻辑。

返回值:int 类型的数字。
在父进程中:成功 返回值是子进程的pid号 >0
失败 返回-1;
在子进程中:成功 返回值 0
失败 无


面试题:
一次fork生成几个进程?他们之间的关系是什么样的?
如果两次fork同时前后执行,会生成几个进程?他们之间的
关系如何表示,有多少个子进程,有没有孙进程?
2.getpid
pid_t getpid(void);
功能:
获得调用该函数进程的pid
参数:
缺省
返回值:
进程的pid
       
3.getppid
pid_t getppid(void);
功能:
获得调用该函数进程的父进程pid号
参数:
缺省
返回值:
返回父进程id号


fork()&&fork()||fork();


while(1)sleep(1);
应用场合:
1)一个进程希望复制自己,使父子进程同时执行同的代码段。网络服务中会比较多见。
2)一个进程需要执行一个不同的程序。fork+exec



使用变量测试,验证位于不同的地址空间。
文件的写入测试。

练习:
设计一个程序,动态生成两个进程,分别向相同的文件中
写入不同的数据,要表明是两个进程同时写入的数据。

./a.out  ===> 1.txt ==>父进程写入的信息 时间+编号(father pid)
时间+编号(child pid)
 父进程1123 186 16:02:10
 子进程1124 188 16:02:15

while(1)
{
//fgets();
fork();
}

父子进程的关系:
子进程是父进程的副本。子进程获得父进程数据段,堆,栈,正文段共享。

在fork之后,一般情况那个会先运行,是不确定的。如果非要确定那个要先运行,需要IPC机制。

区别:
1)fork的返回值
2)pid不同


进程的终止:8中情况
1)main 中return
2)exit(), c库函数,会执行io库的清理工作,关闭所有 的流,以及所有打开的文件。已经清理函数(atexit)。
3)_exit,_Exit 会关闭所有的已经打开的文件,不执行清理函数。
4) 主线程退出
5)主线程调用pthread_exit
异常终止
6)abort()
7)signal   kill pid
8)最后一个线程被pthread_cancle







2.进程的退出

僵尸进程和孤儿进程

僵尸进程:进程执行结束但空间未被回收变成僵尸进程

1.exit     库函数
退出状态,终止的进程会通知父进程,自己使如何终止的。如果是正常结束(终止),则由exit传入的参数。如果是异常终止,则有内核通知异常终止原因的状态。任何情况下,负进程都能使用wait,waitpid获得这个状态,以及资源的回收。
void exit(int status) 
exit(1);
功能:
让进程退出,并刷新缓存区
参数:
status:进程退出的状态
返回值:
缺省

EXIT_SUCCESS 0
EXIT_FAILURE 1

return  当该关键字出现在main函数中时候可以结束进程
如果在其他函数中则表示结束该函数。
exit -> 刷新缓存区 -> atexit注册的退出函数 -> _exit

2._exit    系统调用
void _exit(int status);
功能:
让进程退出,不刷新缓存区
参数:
status:进程退出状态
返回值:
缺省


 mian(int agc,argv)
{
main();
}  

回调函数
3.atexit
int atexit(void (*function)(void));
功能:
注册进程退出前执行的函数
参数:
function:函数指针
指向void返回值void参数的函数指针
返回值:
成功返回0
失败返回非0

当程序调用exit或者由main函数执行return时,所有用atexit
注册的退出函数,将会由注册时顺序倒序被调用

3.进程空间的回收

exit(20);

wait/waitpid

pid_t wait(int *status);
功能:该函数可以阻塞等待任意子进程退出
      并回收该进程的状态。
  一般用于父进程回收子进程状态。

参数:status 进程退出时候的状态
  如果不关心其退出状态一般用NULL表示
  如果要回收进程退出状态,则用WEXITSTATUS回收。

返回值:成功 回收的子进程pid
失败 -1;

WIFEXITED(status)  是不是正常结束
   

WEXITSTATUS(status) 使用这个宏去那返回值

WIFSIGNALED(status) 是不是收到了信号而终止的
              

WTERMSIG(status)如果是信号终止的,那么是几号信号。


练习:
设计多进程测试程序,完成字符和字符串作为
exit返回的状态,查看是否能完成资源与数据
的回收。

pid_t wait(int *status);

1)如果所有的子进程都在运行,在阻塞
2)如果一个子进程终止,正在等待的父进程则获得终止状态,获得子进程的状态后,立刻返回。
3)如果没有子进程,则立即出错退出。

waitpid(-1,status,0)=wait(status);
pid_t waitpid(pid_t pid, int *status, int options);
< -1 回收指定进程组内的任意子进程
-1 回收任意子进程,组内外
0 回收和当前调用waitpid一个组的所有子进程,组内
> 0 回收指定ID的子进程
 waitpid (-1,a,0)  == wait(a);
 status 子进程退出时候的状态,
   如果不关注退出状态用NULL;
  options 选项:
   0  表示回收过程会阻塞等待
WNOHANG 表示非阻塞模式回收资源。
返回值:成功 返回接收资源的子进程pid
失败  -1
0,

EAGAIN


练习:
设计一个多进程程序,用waitpid函数指定回收
其中的某个进程资源并将其状态打印输出。
其他的进程都以非阻塞方式进行资源回收。


exec

execute
exec族
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),
子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的
用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建
新进程,所以调用exec前后该进程的id并未改变。
其实有六种以exec开头的函数,统称exec函数:
vector
ls -l -i list 
execl("/bin/ls","-l","-i",NULL);
execlp("ls","-l","-i",NULL);
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[]);

key=value
int execle(const char *path, const char *arg, ..., char *const envp[]);
int execle(const char *path, const char *arg, ..., char *const envp[]);

int execve(const char*path,char*const argv[],char*const evnp[]);
int execlp(const char *file, const char *arg, ...);
echo $PATH
PATH= 
int execvp(const char *file, char *const argv[]);

加载更多

int execve(const char *path, char *const argv[], char *const envp[]);

这些函数的区别
1),前4个使用路径名作为参数,后面两个使用文件名做参数
当filename中,含有/时视为路径名,否则就按PATH变量,在指定目录下查找可执行文件。
2)相关的参数表传递
l表示list,v表示vector
execl,execlp,execle,需要将参数一个一个列出,并以NULL结尾。
execv,execvp,execve,需要构造一个参数指针数组,然后将数组的地址传入。

3)以e结尾的函数,可以传入一个指向环境字符串的指针数组的指针。其他未指定环境变量,使用父进程继承过来的。
execve 是真正的系统调用
这些函数如果调用成功则加载新的程序从启动代码开始执行,不再返回,如果调用出错
则返回-1,所以exec函数只有出错的返回值而没有成功的返回值。



char *const ps_argv[] ={"ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL};
char *const ps_envp[] ={"PATH=/bin:/usr/bin", "TERM=console", NULL};
execl("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
execv("/bin/ps", ps_argv);
execle("/bin/ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL, ps_envp);
execve("/bin/ps", ps_argv, ps_envp);
execlp("ps", "ps", "-o", "pid,ppid,pgrp,session,tpgid,comm", NULL);
execvp("ps", ps_argv);



2017-11-5 17:00:20 当前进程数是?


学习产出:

练习:
1、 设计一个进程,默认读取同名配置文件。
根据配置文件的内容,启动相关程序,并将
daemon.cfg
ls /etc/ -l 
ps aux 
cp /etc/passwd ./ 
daemon.log
2017-8-17 13:39:23 ls 
2017-8-17 13:29:30 ps
2017-8-17 13:29:30 cp 
启动过程信息(时间,pid) 写入同名日志文件。

标签:ps,const,int,编程,pid,char,Linux,进程
From: https://blog.csdn.net/qq_61802519/article/details/140475452

相关文章

  • Linux常用命令
    目录pstopfindgreptailtarziphistorywatchtailchownchmodsudf/ducpucpps常见用法:psaufx各个字段的含义:USER:表示哪个用户启动了这个进程PID:进程ID%CPU:进程CPU的占用率%MEM:进程物理内存的占用率VSZ:进程占用的虚拟内存量(Kbytes)RSS:进程当前实际上占用了多少内存TTY......
  • Linux性能分析工具Perf
    Linux性能分析工具Perf介绍Perf全名是PerformanceEvent,是在Linux2.6.31以后内建的系统效能分析工具,依靠perf,应用程式可以利用PMU(PerformanceMonitoringUnit),tracepoint和核心内部的特殊计数器(counter)来进行统计,另外还能同时分析运行中的核心程式码,从而更全面了解应用......
  • Linux捣鼓记录:debian12安装xfce桌面环境
    在Debian12上安装Xfce桌面第1步。在安装任何软件包之前,建议更新软件包列表以确保您安装的是最新版本的软件包。您可以通过在终端中运行以下命令来执行此操作:sudoaptupdate&&sudoaptupgrade此命令将刷新存储库,允许您安装最新版本的软件包。第2步。在Debian12......
  • 教你如何管理Linux网络,一招鲜吃遍天?!
    01准备工作当前操作的虚拟机版本信息:CentOS8当前操作的虚拟化软件:VMwareworkstation由于虚拟化软件中有3种网络模式,我们这里选择使用NAT模式提前查看虚拟机的网段信息是多少,方便我们后续配置网络能够有效使用在配置网络之前您需要了解一些基础知识:在给Linux系统配置网络......
  • Mojo AI编程语言(十二)高级特性:深入理解Mojo
    目录1.Mojo简介2.高级数据类型2.1数组与矩阵2.2多维数组2.3字符串操作3.并行计算3.1线程与协程3.2并行算法4.分布式系统4.1RPC与消息传递4.2分布式数据处理5.高级语言特性5.1泛型编程5.2函数式编程5.3元编程6.错误处理与调试6.1错误处理6.2......
  • 关于如何在Arch Linux上编写自己的第一个module
    前一段时间一直想深入学习编写一个module插入到自己的内核当中,但是网上的资料基本上全都针对的Ubuntu和Debian等流行的Linux发行版,这里打算简单的记录一波博客。啥是Module?(着急可不看)众所周知:现代宏内核架构的操作系统都会借鉴微内核当中比较有价值的设计思想,这里的modules正......
  • Rocky Linux-监控-day4
    监控概述监控的目的报告系统运行状况,了解内容包括吞吐量、反应时间、使用率等提前发现问题,提前解决问题进行服务器性能调整前,知道调整什么找出系统的瓶颈监控的资源类别公开数据Web、FTP、SSH、数据库等应用服务TCP或UDP端口私有数据CPU、内存、磁盘......
  • 全网最详细!! Linux 安装、配置教程
    一、下载安装包        首先去官网下载VMware最新版本,以及发行版CentOS-7,懒得下载的可以私信我,我给你发包    其中,CentOS(CommunityEnterpriseOperatingSystem)是一个基于Linux的开源操作系统,它是从RedHatEnterpriseLinux(RHEL)源代码衍生而来的。CentOS......
  • QT网络编程(二)——TCP协议工作原理及实战
    目录引言一、TCP协议基础知识1.TCP协议特点2.TCP连接的三个阶段3.三次握手和四次挥手二、Qt中的TCP编程1.引入Qt网络模块2.QTcpServer类常用函数3.QTcpSocket类常用函数三、TCP网络通信流程TCP服务器TCP客户端四、实战示例UI界面核心代码运行结果......
  • ArchLinux 问题集锦
    电脑使用Android的网络sudopacman-Susb_modeswitch手机打开网络共享Android使用usb连接电脑网络yay-SgnirehtegnirehtetrunAndroid投屏到电脑sudopacman-SscrcpyscrcpyPlasmaKDEScreenLockingPictureoftheDay每日一图的图片缓存位置~/.cache/pla......