管理概念
先描述,再组织
进程
启动一个软件就相当于启动了一个进程
Linux下执行一条命令就在系统层面创建了一个进程!!
如何管理
进程=对应的代码和数据 + 进程对应的PCB结构体
PCB(process control block)
在Linux系统中,可以使用以下几种方式获取进程的PID(进程ID):
- getpid()函数:可以使用C/C++的系统调用函数
getpid()
来获取当前进程的PID。该函数定义在<sys/types.h>
头文件中。
#include <sys/types.h>
#include <unistd.h>
int main() {
pid_t pid = getpid();
printf("当前进程的PID:%d\n", pid);
return 0;
}
- ps命令:在终端中可以使用
ps
命令来查看当前正在运行的进程以及它们的PID。常用的ps
命令选项包括-e
(显示所有进程)、-f
(显示完整格式)和-l
(显示更详细的信息)。
ps -ef
- pgrep命令:
pgrep
命令是一个用于根据进程名或其他属性查找进程PID的命令。可以使用pgrep
命令来查找指定进程名的PID。
命令ps axj | grep myproc
它将显示包含 “myproc” 关键字的进程信息。
解释一下这个命令的每个部分:
ps
命令用于显示当前正在运行的进程信息。axj
选项组合用于显示所有进程的详细信息,并使用类似于BSD风格的输出格式。|
管道符将ps
命令的输出传递给grep
命令。grep
命令用于过滤包含 “myproc” 关键字的行。
因此,ps axj | grep myproc
命令将显示所有包含 “myproc” 关键字的进程信息。
ps axj | head -1 #显示头部
pgrep <进程名>
- /proc文件系统:Linux系统中的
/proc
目录是一个虚拟文件系统,可以通过读取其中的文件来获取进程相关的信息,包括PID。可以使用/proc/self
来获取当前进程的PID。
cat /proc/self/status | grep "Pid"
-
pidof命令:pidof命令用于根据进程名获取进程的PID。
pidof <进程名>
例如,要获取名为 “myproc” 的进程的PID,可以使用以下命令: -
pidof myproc
top命令:top命令用于实时显示系统中运行的进程和系统资源的使用情况。
top
在top命令的输出中,可以查找特定进程的PID。
kill -9 进程编号
man getppid
获得父进程id
fork
创建子进程,之后父子共享代码
这个结果会打印出两个“you can see me!”
孤儿进程
孤儿进程会被领养,被1号进程领养(init,系统本身)
进程优先级
有优先级原因:CPU有限,进程太多,需要通过某种方式竞争
==什么是优先级?==谁先应该获得某种资源,谁后获得:我们可以用一些数据来表示优先级
在Linux系统中,进程的优先级由nice值来表示。nice值是一个整数,范围通常是-20到+19,其中-20表示最高优先级,+19表示最低优先级。
在Linux系统中,通过nice命令可以查看和修改进程的nice值。以下是一些常用的命令和方法:
-
查看进程的nice值:可以使用
ps
命令结合-o nice
选项来查看进程的nice值。例如,ps -o nice -p <pid>
可以查看指定进程的nice值。 -
修改进程的nice值:可以使用
renice
命令来修改进程的nice值。例如,renice -n <nice值> -p <pid>
可以将指定进程的nice值修改为指定的值。需要注意的是,修改nice值需要有足够的权限,通常需要使用root用户或具有相应权限的用户。 -
设置进程的默认nice值(80):可以使用
nice
命令来启动一个新进程,并指定其默认的nice值。例如,nice -n <nice值> <command>
可以启动一个新进程,并将其默认的nice值设置为指定的值。
需要注意的是,较低的nice值表示较高的优先级。因此,较小的nice值的进程会更早地得到CPU资源,而较大的nice值的进程会相对较晚地得到CPU资源。
此外,Linux系统还使用其他调度算法来决定进程的调度顺序,如CFS(Completely Fair Scheduler)调度算法。CFS调度算法根据进程的虚拟运行时间和进程的优先级等因素来进行调度,nice值只是其中的一个因素。
调整命令
renice #运行时调
nice #启动时调
进程的特点
环境变量
设置一个新的环境变量 一般重启后就会消失
char *env[] 即环境变量参数 (从父进程继承过来的)
argc *argv[ ] 命名行参数
argc
和argv
是用于处理命令行参数的两个变量。
argc
是一个整数,表示命令行参数的数量。它包括了程序本身的名称,因此至少为1。例如,如果你在命令行中执行./program arg1 arg2
,那么argc
的值将为3。
argv
是一个指向指针的数组,每个指针指向一个字符串,表示一个命令行参数。第一个参数argv[0]
通常是程序的名称,后续的参数argv[1]
、argv[2]
等依次表示其他的命令行参数。例如,对于上面的例子,argv[0]
将是./program
,argv[1]
将是arg1
,argv[2]
将是arg2
。
下面是一个简单的示例,演示了如何使用argc
和argv
来处理命令行参数:
#include <iostream>
int main(int argc, char* argv[]) {
std::cout << "命令行参数的数量为:" << argc << std::endl;
for (int i = 0; i < argc; i++) {
std::cout << "参数 " << i << ": " << argv[i] << std::endl;
}
return 0;
}
在上面的示例中,我们使用main
函数的参数列表来接收argc
和argv
。然后,我们使用argc
打印命令行参数的数量,并使用一个循环遍历argv
数组,打印每个命令行参数的值。
通过使用argc
和argv
,你可以在程序中根据命令行参数的不同执行不同的操作,或者根据参数的值进行相应的处理。
希望这个解释对你有帮助!如果还有其他问题,请随时提问。
进程地址空间(程序地址空间)
进程地址空间(也称为程序地址空间)是操作系统为每个运行的进程分配的一块内存空间,用于存储该进程的代码、数据和堆栈等信息。进程地址空间是一个虚拟的内存空间,它为进程提供了独立的内存环境,使得每个进程都可以在自己的地址空间中执行,而不会干扰其他进程的内存空间。
进程地址空间通常被划分为以下几个部分:
-
代码段(Text Segment):用于存储程序的可执行代码,通常是只读的。
-
数据段(Data Segment):用于存储全局变量和静态变量等数据。
-
堆(Heap):用于动态分配内存,由程序员通过调用malloc()、new等函数手动管理。
-
栈(Stack):用于存储局部变量、函数调用和函数返回等信息,由编译器自动管理。
-
共享库(Shared Libraries):用于存储共享库的代码和数据,多个进程可以共享同一个共享库的实例。
进程地址空间的大小是由操作系统在进程创建时确定的,通常是固定的。不同的操作系统和架构可能有不同的地址空间大小限制。
进程地址空间的划分和管理由操作系统负责。操作系统通过虚拟内存管理机制,将进程的虚拟地址映射到物理内存上,实现了地址空间的隔离和保护。这样,每个进程都可以独立地访问自己的地址空间,而不会影响其他进程的内存。