Linux系统编程系列之进程基础

一、什么是进程

        关于进程的定义很多,这里讲一种比较直接的,进程就是程序中的代码和数据被加载到内存中运行的过程,就是程序的执行过程。进程是动态的,而程序是静态的。程序存储在硬盘里,进程只有在程序被执行后,才存在,而且存在于内存中。具体看下图:

Linux系统编程系列之进程基础_第1张图片

        在Linux系统中,程序的格式都是ELF,这些文件在被执行的瞬间,就被载入内存,所谓的载入内存,如上图所示,就是将数据段,代码段这些运行时必要的资源拷贝到内存,另外系统会再分配相应的栈、堆等内存空间给这个进程,使之成为一个动态的实体。

        二、进程的组织方式

        在Linux系统中,除了系统的初始进程之外,其余所有的进程都是从一个父进程fork而来的,因此,所有的进程都起源于相同的初始进程,它们之间形成一棵倒置的进程树,使用命令pstree查看进程的关系:

 gec@ubuntu:~$ pstree
systemd─┬─ModemManager───2*[{ModemManager}]
        ├─NetworkManager───2*[{NetworkManager}]
        ├─VGAuthService
        ├─accounts-daemon───2*[{accounts-daemon}]
        ├─acpid
        ├─anacron
        ├─apt.systemd.dai───apt.systemd.dai───unattended-upgr───2*[{unattended-upgr}]
        ├─avahi-daemon───avahi-daemon
        ├─bluetoothd
        ├─colord───2*[{colord}]
        ├─cron
        ├─cups-browsed───2*[{cups-browsed}]
        ├─cupsd
        ├─2*[dbus-daemon]
        ├─fcitx
        ├─fcitx-dbus-watc
        ├─gdm3─┬─gdm-session-wor─┬─gdm-x-session─┬─Xorg───{Xorg}
        │      │                 │               ├─gnome-session-b─┬─fcitx
        │      │                 │               │                 ├─ssh-agent
        │      │                 │               │                 └─2*[{gnome-session-b}]
        │      │                 │               └─2*[{gdm-x-session}]
        │      │                 └─2*[{gdm-session-wor}]
        │      └─2*[{gdm3}]
        ├─gnome-keyring-d───3*[{gnome-keyring-d}]
        ├─irqbalance───{irqbalance}
        ├─2*[kerneloops]
        ├─networkd-dispat
        ├─polkitd───2*[{polkitd}]
        ├─rsyslogd───3*[{rsyslogd}]
        ├─rtkit-daemon───2*[{rtkit-daemon}]
        ├─snapd───12*[{snapd}]
        ├─sshd
        ├─switcheroo-cont───2*[{switcheroo-cont}]
        ├─systemd─┬─(sd-pam)
        │         ├─at-spi-bus-laun─┬─dbus-daemon
        │         │                 └─3*[{at-spi-bus-laun}]
        │         ├─at-spi2-registr───2*[{at-spi2-registr}]
        │         ├─dbus-daemon
        │         ├─dconf-service───2*[{dconf-service}]
        │         ├─evolution-addre───5*[{evolution-addre}]
        │         ├─evolution-calen───8*[{evolution-calen}]
        │         ├─evolution-sourc───3*[{evolution-sourc}]
        │         ├─gjs───4*[{gjs}]
        │         ├─gnome-session-b─┬─evolution-alarm───5*[{evolution-alarm}]
        │         │                 ├─gsd-disk-utilit───2*[{gsd-disk-utilit}]
        │         │                 ├─update-notifier───3*[{update-notifier}]
        │         │                 └─3*[{gnome-session-b}]
        │         ├─gnome-session-c───{gnome-session-c}
        │         ├─gnome-shell─┬─ibus-daemon─┬─ibus-engine-sim───2*[{ibus-engine-sim}]
        │         │             │             ├─ibus-extension-───3*[{ibus-extension-}]
        │         │             │             ├─ibus-memconf───2*[{ibus-memconf}]
        │         │             │             └─2*[{ibus-daemon}]
        │         │             └─7*[{gnome-shell}]
        │         ├─gnome-shell-cal───5*[{gnome-shell-cal}]
        │         ├─gnome-terminal-─┬─bash───pstree
        │         │                 ├─bash
        │         │                 └─4*[{gnome-terminal-}]
        │         ├─goa-daemon───3*[{goa-daemon}]
        │         ├─goa-identity-se───2*[{goa-identity-se}]
        │         ├─gsd-a11y-settin───3*[{gsd-a11y-settin}]
        │         ├─gsd-color───3*[{gsd-color}]
        │         ├─gsd-datetime───3*[{gsd-datetime}]
        │         ├─gsd-housekeepin───3*[{gsd-housekeepin}]
        │         ├─gsd-keyboard───3*[{gsd-keyboard}]
        │         ├─gsd-media-keys───3*[{gsd-media-keys}]
        │         ├─gsd-power───3*[{gsd-power}]
        │         ├─gsd-print-notif───2*[{gsd-print-notif}]
        │         ├─gsd-printer───2*[{gsd-printer}]
        │         ├─gsd-rfkill───2*[{gsd-rfkill}]
        │         ├─gsd-screensaver───2*[{gsd-screensaver}]
        │         ├─gsd-sharing───3*[{gsd-sharing}]
        │         ├─gsd-smartcard───4*[{gsd-smartcard}]
        │         ├─gsd-sound───3*[{gsd-sound}]
        │         ├─gsd-usb-protect───3*[{gsd-usb-protect}]
        │         ├─gsd-wacom───2*[{gsd-wacom}]
        │         ├─gsd-wwan───3*[{gsd-wwan}]
        │         ├─gsd-xsettings───3*[{gsd-xsettings}]
        │         ├─gvfs-afc-volume───3*[{gvfs-afc-volume}]
        │         ├─gvfs-goa-volume───2*[{gvfs-goa-volume}]
        │         ├─gvfs-gphoto2-vo───2*[{gvfs-gphoto2-vo}]
        │         ├─gvfs-mtp-volume───2*[{gvfs-mtp-volume}]
        │         ├─gvfs-udisks2-vo───3*[{gvfs-udisks2-vo}]
        │         ├─gvfsd─┬─gvfsd-trash───2*[{gvfsd-trash}]
        │         │       └─2*[{gvfsd}]
        │         ├─gvfsd-fuse───5*[{gvfsd-fuse}]
        │         ├─gvfsd-metadata───2*[{gvfsd-metadata}]
        │         ├─ibus-portal───2*[{ibus-portal}]
        │         ├─ibus-x11───2*[{ibus-x11}]
        │         ├─pulseaudio───3*[{pulseaudio}]
        │         ├─snap-store───4*[{snap-store}]
        │         ├─tracker-miner-f───4*[{tracker-miner-f}]
        │         ├─vmtoolsd───3*[{vmtoolsd}]
        │         ├─xdg-desktop-por───5*[{xdg-desktop-por}]
        │         ├─xdg-desktop-por───3*[{xdg-desktop-por}]
        │         ├─xdg-document-po───6*[{xdg-document-po}]
        │         └─xdg-permission-───2*[{xdg-permission-}]
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-network
        ├─systemd-resolve
        ├─systemd-timesyn───{systemd-timesyn}
        ├─systemd-udevd
        ├─udisksd───4*[{udisksd}]
        ├─unattended-upgr───{unattended-upgr}
        ├─upowerd───2*[{upowerd}]
        ├─vmhgfs-fuse───8*[{vmhgfs-fuse}]
        ├─vmtoolsd───3*[{vmtoolsd}]
        ├─vmware-vmblock-───3*[{vmware-vmblock-}]
        ├─whoopsie───2*[{whoopsie}]
        └─wpa_supplicant
gec@ubuntu:~$ 

     Linux系统编程系列之进程基础_第2张图片

          由上图可知,最开始的系统进程叫systemd(CentOS7之后,systemd取代init,也就是1号进程,更早的进程是idle,0号进程)。

        init进程由idle通过kernel_thread创建,在内核空间完成初始化后,加载init程序,进入最终用户空间,然后启动其他系统进程。在系统启动完成后,init将变成为守护进程监视系统其他进程。

(这里不详细讲,在另外一篇博客讲)。

三、进程的状态

Linux系统编程系列之进程基础_第3张图片

        1、所有进程(除了系统初始进程systemd之外)都有一个父进程。

        2、父进程通过调用fork()函数,将自身复制一份形成一个子进程。

        3、新创建的子进程拥有与父进程一样的执行代码、内存空间(父子进程的内存空间的内容是一致的,但分属不同的区域各自独立)等信息,并处于就绪态(TASK_RUNNING)。

        4、当进程退出时(不管是主动退出还是被动退出),进入僵尸态(EXIT_ZOMBIE),僵尸态下的进程无法运行,也无法被调度,但其所占据的系统资源未被释放。僵尸态是进程的必经状态,编程过程中不可能避免僵尸态,但要避免进程长时间处于僵尸态。

        5、僵尸态进程要等待其父进程对其资源进程回收后,才能变成死亡态(EXIT_DEAD),死亡态的进程所占据的系统资源可以被系统随时回收。

你可能感兴趣的:(Linux,大学课程知识,C语言程序设计,linux)