Linux —— 进程介绍

进程是操作系统中的执行实体,具有独立的地址空间和资源。PCB(进程控制块)用于存储进程信息,如状态、标识符等。task_struct是Linux中实现PCB的数据结构。fork系统调用用于创建子进程,子进程继承父进程的大部分属性但拥有独立的进程ID。可以通过/proc文件系统查看进程信息。
摘要由CSDN通过智能技术生成

目录

一,进程介绍

二,进程使用

进程查看

通过系统调用获取进程标识符

通过系统调用创建进程 fork


一,进程介绍

        进程是正在执行的程序或命令,每个进程都是一个运行的实体或程序的执行实例,有自己的地址空间,并占用一定系统资源;从内核视角来看,是担当分配系统资源(CPU时间、内存)的实体;

  • 即在操作系统中,所有可执行的程序或命令都会产生进程(如简单的命令ls、touch等,执行完即结束,如httpd启动后就一直驻留在系统中的常驻内存进程);
  • 程序在执行时,执行者的权限和属性均会载入内存,操作系统会对进程分配一个ID,称为进程ID(即PID);
  • 进程可以产生新的进程,称此进程为父进程,新进程为子进程,如bash中执行的ls、touch等命令(bash父进程、ls/touch子进程);即子进程是依赖父进程产生的,若无父进程,子进程也就不存在;

进程控制块 PCB

        操作系统负责管理所有进程,包括进程的创建和消亡、进程状态的转换,及分配和回收进程所需的资源等;为了描述控制进程的运行,系统中存放进程的管理和控制信息的数据结构称为进程控制块(PCB Process Control Block);

  • PBC是进程实体的一部分,是操作系统中最重要的记录性数据结构;
  • PBC是进程管理和控制的最重要的数据结构,每一个进程均有一个PCB,在创建进程时,建立PCB,伴随进程运行的全过程,直到进程撤消而撤消;

        操作系统创建进程时,会额外申请一块内存(即进程控制块),用于存储、管理和控制进程的信息;由操作系统负责管理和维护,进程和进程控制块数量是对应的;Linux系统的PCB/task_struct;

  • task_struct(PCB的一种),描述进程的结构体;
  • task_struct 是Linux内核的一种数据结构,会被载入到内存并包含进程信息;
  • 运行在系统里的进程,都是以task_struct链表形式存在于内核内;对进程的管理,即是对此链表的增删查改;

task_struct 内容

  • 标识符,描述进程的唯一标识符,区别其他进程;
  • 状态,任务状态、退出代码、退出信息等;
  • 优先级,相当于其他进程的优先级;
  • 程序计数器,即将被执行下一指令的地址;
  • 内存指针,包括程序代码和进程相关数据的指针,及与其他进程共享的内存块指针;
  • 上下文数据,进程执行时寄存器中的数据;
    • 上下文数据即进程暂停执行保存的所有临时数据;
  • I/O状态信息,包括显式的I/O请求,分配给进程的I/O设备和被进程使用的文件列表;
  • 记账信息,可能包括处理器时间总和,使用时钟数总和,时间限制,记账号等;
  • 其他信息;

注:管理的本质是先描述在组织;进程 = 程序 + PCB;

查看内核路径:..\linux-6.4.3\include\linux\sched.h

二,进程使用

        进程查看、系统调用获取标识符及创建子进程;

进程查看

  • 进程信息存于 /proc 文件夹,可通过此文件夹查看;
[wz@192 ~]$ ll /proc
total 0
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 1
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 10
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 11
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 1180
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 1182
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 1183
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 1187
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 1193
dr-xr-xr-x.  9 root           root                         0 7月   9 06:35 12
...
[wz@192 Desktop]$ ll /proc/59017
total 0
dr-xr-xr-x. 2 wz wz 0 7月  12 09:17 attr
-rw-r--r--. 1 wz wz 0 7月  12 09:17 autogroup
-r--------. 1 wz wz 0 7月  12 09:17 auxv
-r--r--r--. 1 wz wz 0 7月  12 09:17 cgroup
--w-------. 1 wz wz 0 7月  12 09:17 clear_refs
-r--r--r--. 1 wz wz 0 7月  12 06:32 cmdline
-rw-r--r--. 1 wz wz 0 7月  12 09:17 comm
-rw-r--r--. 1 wz wz 0 7月  12 09:17 coredump_filter
-r--r--r--. 1 wz wz 0 7月  12 09:17 cpuset
lrwxrwxrwx. 1 wz wz 0 7月  12 09:17 cwd -> /home/wz/Desktop
-r--------. 1 wz wz 0 7月  12 09:17 environ
lrwxrwxrwx. 1 wz wz 0 7月  12 06:32 exe -> /usr/bin/bash
  • 可通过命令top(动态查看)、ps(静态查看)、pstree(程序树),来查看大多数进程信息;

[wz@192 Desktop]$ ps axj | head -1 && ps axj | grep bash
  PPID    PID   PGID    SID TTY       TPGID STAT   UID   TIME COMMAND
     1    781    765    765 ?            -1 S        0   0:17 /bin/bash /usr/sbin/ksmtuned
  2107   2244   2244   2244 ?            -1 Ss    1000   0:02 /usr/bin/ssh-agent /bin/sh -c exec -l /bin/bash -c "env GNOME_SHELL_SESSION_MODE=classic gnome-session --session gnome-classic"
 59010  59017  59017  59017 pts/0     61546 Ss    1000   0:00 bash
 59017  61547  61546  59017 pts/0     61546 S+    1000   0:00 grep --color=auto bash

通过系统调用获取进程标识符

  • 进程id为PID;
  • 父进程id为PPID;
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    printf("pid: %d\n", getpid());
    printf("ppid: %d\n", getppid());
    return 0;
}

通过系统调用创建进程 fork

        fork() 通过复制正在调用的进程,来创建新进程;新进程将作为子进程,是父进程的完全副本;

  • fork有两个返回值,0代表子进程,大于0代表父进程;
    • 子进程返回0;
    • 父进程返回子进程的ID;
  • 子进程有自己唯一进程ID(PID);
  • 父子进程代码共享(只读),数据各自私有一份 ,采用写实拷贝;各自独立,互不干扰;
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    int ret = fork();
    printf("hello proc : %d!, ret: %d\n", getpid(), ret);
    sleep(1);
    return 0;
}
  • fork通常使用if进行分流;
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    int ret = fork();
    if(ret < 0){
        perror("fork");
        return 1;
    }
    else if(ret == 0)
    { 
        printf("I am child : %d!, ret: %d\n", getpid(), ret); //child
    }
    else
    { 
        printf("I am father : %d!, ret: %d\n", getpid(), ret); //father
    }
    sleep(1);
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值