進程 進程的狀態及轉換 進程控制塊 進程號 進程的創建 fork 函數 進程的掛起 進程的等待 進程的等待 進程退出清理 進程的創建 vfork 函數 進程的替換 system 函數

進程概述

    進程的定義

        程序:

             程序是存放在存儲介質上的一個可執行文件

       進程:

             進程是程序的執行實例, 包括程序計數器、 寄存器和變量的當前值

       程序是靜態的, 進程是動態的

       程序是一些指令的有序集合, 而進程是程序執行的過程

       進程的狀態是變化的, 其包括進程的創建、 調度和消亡

      在 linux 系統中, 進程是管理事務的基本單元

      進程擁有自己獨立的處理環境和系統資源(處理器、 存儲器、I/O 設備、 數據、 程序)

      可用 exec 函數由內核將程序讀入內存, 使其執行起來成爲一個進程
 

    進程的狀態及轉換

           進程整個生命週期 可簡單劃分爲三種狀態:

                就緒態:
                    進程已具備執行的一切條件, 正在等待分配 CPU 的處理時間
               執行態:
                     該進程正在佔用 CPU 運行
               等待態:
                   進程因不具備某些執行條件,而暫時無法繼續執行的狀態

        進程三種狀態的轉換關係:

    進程控制塊

           OS 是根據 PCB ,對併發執行的進程進行 控制和管理

          系統在創建一個進程的時,會開闢一段內存空間存放與此進程相關 的 PCB 數據結構

          PCB 是操作系統中最重要的記錄型數據結構

          PCB 中記錄用於 描述進程進展情況及 控制進程運行所需的全部信息

          PCB 是進程存在的唯一標誌, 在 Linux 中 PCB 存放在 task_struct 結構體中

        調度數據:

             進程的狀態、 標誌、 優先級、 調度策略等

       時間數據:

          創建該進程的時間、 在用戶態的運行時間、 在內核態的運行時間等

      文件系統數據:

            umask 掩碼、 文件描述符表等

      內存數據、 進程上下文、 進程標識(進程號)

進程控制

    進程號

         每個進程都由一個進程號來標識, 其類型爲 pid_t, 進程號的範圍: 0~32767( 2^15 )

         進程號總是唯一的, 但進程號可以重用

         當一個進程終止後, 其進程號就可以再次使用了

          在 linux 系統中進程號由 0 開始

               進程號爲 0 及 1 的進程由內核創建

                      進程號爲 0 的進程通常是調度進程, 常被稱爲交換進程(swapper)

                      進程號爲 1 的進程通常是 init 進程

            除調度進程外, 在 linux 下面所有的進程都由 進程 init 進程直接或者間接創建

        進程號(PID):

              標識進程的一個非負整型數

         父進程號(PPID):

              任何進程(除 init 進程)都是由另一個進程創建, 該進程稱爲 被創建進程的父進程, 對應的進程號稱爲父進
程號(PPID)

        進程組號(PGID):

              進程組是一個或多個進程的集合

             他們之間相互關聯, 進程組可以接收同一終端的各種信號,關聯的進程有一個進程組號(PGID)

        Linux 操作系統提供了三個獲得進程號的函數 getpid()、 getppid()、 getpgid()

例子:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    pid_t pid;
    pid_t ppid;
    pid_t pgid;

    // 獲取本進程號
    pid = getpid();
    // 獲取調用此函數的進程的父進程號
    ppid = getppid();
    // 獲取進程組號,參數爲 0 時返回當前 PGID, 否則返回參數指定的進程的 PGID
    pgid = getpgid(pid);

    printf("pid = %d\n",pid);
    printf("ppid = %d\n",ppid);
    printf("pgid = %d\n",pgid);
    return 0;
}

    進程的創建 fork 函數

#include <sys/types.h>
#include <unistd.h>

/*
 * 從一個已存在的進程中創建一個新進程, 新進程稱爲子進程, 原進程稱爲父進程
 *return:
 *     成功:子進程返回0 父進程返回子進程ID
 *     錯誤:-1
 */
pid_t fork(void);
pid_t vfork(void);

        地址空間:
             進程上下文、 進程堆棧、 打開的文件描述符、 信號控制設定、 進程優先級、 進程組號
            子進程所獨有的只有它的進程號, 計時器
 

 創建一個子進程實現多任務:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    pit_t pid;
    
    pid = frok();
    if(pid < 0)
    {
        perror("fork");
    }

    if(0 == pid)
    {
        while(1)
        {
            printf("this is son process\n");
            sleep(1);
        }
    }
    else
    {
        while(1)
        {
            printf("this is father process\n");
            sleep(1);
        }
    }
    return 0;
}

驗證父子進程分別有各自獨立的地址空間

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int var = 10;

int main(int argc, char *argv[])
{
    pid_t pid;
    int num = 9;

    pid = fork();
    if(pid < 0)
    {
        perror("fork");
    }

    if(0 == pid)
    {
        var++;
        num++;
        printf("in son process var = %d, num = %d\n",var, num);
    }
    else
    {
        sleep(1);
        printf("in father process var= %d, num = %d\n",var, num);
    }
    printf("common code area\n");
    return 0;
}

 

 

 

    進程的掛起

 

    進程的等待

 

    進程的終止

 

    進程退出

 

    清理進程的創建 vfork 函數

 

    進程的替換

 

    system 函數

 

    練習

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章