欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言超詳細(xì)分析多進(jìn)程的概念與使用

 更新時(shí)間:2022年08月16日 09:49:25   作者:lhb2998658795  
在一個(gè)項(xiàng)目中并發(fā)執(zhí)行任務(wù)時(shí)多數(shù)情況下都會選擇多線程,但有時(shí)候也會選擇多進(jìn)程,例如可以同時(shí)運(yùn)行n個(gè)記事本編輯不同文本,由一個(gè)命令跳轉(zhuǎn)到另外一個(gè)命令,或者使用不同進(jìn)程進(jìn)行協(xié)作

1.多進(jìn)程相關(guān)概念

1.1什么是進(jìn)程

進(jìn)程:程序的一次執(zhí)行過程就會產(chǎn)生一個(gè)進(jìn)程。進(jìn)程是分配資源的最小單位(0-3G)。

進(jìn)程就是一個(gè)正在執(zhí)行的任務(wù)。進(jìn)程是一個(gè)動(dòng)態(tài)的過程,它有生命周期隨著程序的運(yùn)行

開始,隨著程序結(jié)束而消亡。每個(gè)進(jìn)程都有自己的獨(dú)立的運(yùn)行的空間,比如每個(gè)進(jìn)程都有

自己的文件描述符,每個(gè)進(jìn)程都擁有自己的緩沖區(qū)。只要用戶執(zhí)行了一個(gè)程序,在內(nèi)核空間

就會創(chuàng)建一個(gè)task_struct的結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體就代表當(dāng)前的進(jìn)程。進(jìn)程運(yùn)行產(chǎn)生的所有

的信息都被放到這個(gè)結(jié)構(gòu)體中保存著。

1.2進(jìn)程和程序有什么區(qū)別

程序:程序是經(jīng)過編譯器編譯生成的二進(jìn)制文件,程序在硬盤上存儲。程序是靜態(tài)的,沒有生命

? 周期的概念程序本身不會分配內(nèi)存。

進(jìn)程:程序的一次執(zhí)行過程就會創(chuàng)建一個(gè)進(jìn)程,進(jìn)程是動(dòng)態(tài)的,有生命周期。進(jìn)程運(yùn)行的時(shí)候會

? 分配0-3G的內(nèi)存空間。進(jìn)程在內(nèi)存上存儲。

1.3進(jìn)程的組成

進(jìn)程是由三個(gè)部分組成的:進(jìn)程的PCB(task_struct),(程序段)文本段,數(shù)據(jù)段。

1.4進(jìn)程的種類

交互進(jìn)程:這種進(jìn)程維護(hù)以一個(gè)終端,通過這個(gè)終端用戶可以和進(jìn)程進(jìn)程交互。

? 例如:文本編輯器

批處理進(jìn)程:這種進(jìn)程優(yōu)先級比較低,運(yùn)行的時(shí)候會被放到一個(gè)運(yùn)行的隊(duì)列中。

? 隨著隊(duì)列的執(zhí)行,而逐漸執(zhí)行。

? 例如gcc編譯程序的時(shí)候這個(gè)進(jìn)程就是批處理進(jìn)程。

守護(hù)進(jìn)程:守護(hù)進(jìn)程就是后臺運(yùn)行的服務(wù),隨著系統(tǒng)的啟動(dòng)而啟動(dòng),隨著系統(tǒng)的終止而終止。

? 例如:windows上的各種服務(wù)

1.5什么是進(jìn)程的PID

PID就是操作系統(tǒng)給進(jìn)程分配的編號,它是識別進(jìn)程的唯一的標(biāo)識。

在linux系統(tǒng)中PID是一個(gè)大于等于0的值。

1.6特殊PID的進(jìn)程

0:idle:在linux系統(tǒng)啟動(dòng)的時(shí)候運(yùn)行的第一個(gè)進(jìn)程就是0號進(jìn)程。

? 如果沒有其他的進(jìn)程執(zhí)行就運(yùn)行這個(gè)idle進(jìn)程。

1:init:1號進(jìn)程是由0號進(jìn)程調(diào)用內(nèi)核kernel_thread函數(shù)產(chǎn)生的第一個(gè)進(jìn)程,

? 它會初始化所有的系統(tǒng)的硬件。當(dāng)初始化完之后會一直執(zhí)行,比如會為

? 孤兒進(jìn)程回收資源。

2:kthreadd:調(diào)度器進(jìn)程,主要負(fù)責(zé)進(jìn)程的調(diào)度工作。

1.7進(jìn)程的狀態(tài)

1.進(jìn)程運(yùn)行的狀態(tài)

D// 不可中斷的休眠態(tài)(信號)

R//運(yùn)行態(tài)

S//可中斷的休眠態(tài)(信號)

T//停止?fàn)顟B(tài)

X//死亡狀態(tài)

Z//僵尸態(tài)(進(jìn)程結(jié)束后沒有被父進(jìn)程回收資源)

2.進(jìn)程的附加狀態(tài)

<//高優(yōu)先級

N//低優(yōu)先級的進(jìn)程

L//在內(nèi)存區(qū)鎖定

s//會話組組長

l//進(jìn)中包含多線程

+//前臺進(jìn)程

二.進(jìn)程實(shí)例

2.1進(jìn)程的拷貝

#include <head.h>
int main(int argc,const char * argv[])
{
    for(int i=0;i<2;i++){
        fork();
        printf("-");
    }
    return 0;
}

原理圖:

分析:上述的程序會打印8個(gè)-,上述程序一共是4個(gè)進(jìn)程,因?yàn)樵谶M(jìn)程創(chuàng)建的時(shí)候會拷貝父進(jìn)程的

緩沖區(qū),由于2214和2215的緩沖區(qū)沒有刷新,所以2216和2217緩沖區(qū)中有兩個(gè)-。

2.2進(jìn)程創(chuàng)建的實(shí)例

#include <head.h>
int main(int argc,const char * argv[])
{
    pid_t pid;
    pid = fork();
    if(pid == -1){
        PRINT_ERR("fork error");
    }else if(pid == 0){
        //子進(jìn)程
        printf("這個(gè)就是子進(jìn)程\n");
    }else{
        //父進(jìn)程
        printf("這個(gè)就是父進(jìn)程\n");
    }
    return 0;
}

分析圖:

2.3執(zhí)行沒有先后循序

#include <head.h>
int main(int argc, const char* argv[])
{
    pid_t pid;
    pid = fork();
    if (pid == -1) {
        PRINT_ERR("fork error");
    } else if (pid == 0) {
        //子進(jìn)程
        while (1) {
            sleep(1);
            printf("這個(gè)就是子進(jìn)程\n");
        }
    } else {
        //父進(jìn)程
        while (1) {
            sleep(1);
            printf("這個(gè)就是父進(jìn)程\n");
        }
    }
    return 0;
}

結(jié)果圖:

2.4進(jìn)程創(chuàng)建的實(shí)例(父子進(jìn)程內(nèi)存空間問題)

父進(jìn)程fork產(chǎn)生子進(jìn)程的時(shí)候利用了寫時(shí)拷貝的原則

2.5使用多進(jìn)程創(chuàng)建三個(gè)進(jìn)程

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    pid_t pid;
    if((pid = fork()) ==-1){
        printf("創(chuàng)建進(jìn)程失敗\n");
        exit(-1);
    }else if(pid == 0){
        pid_t tid;
        if((tid = fork())==-1){
            printf("%d,%d\n",getpid(),getppid());
        }else if(pid == 0){
            printf("%d,%d\n",getpid(),getppid());
        }else{
            printf("%d\n",getpid());
        }
    }
    while(1);
    return 0;
}

2.6使用多進(jìn)程進(jìn)行拷貝文件

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
char destfile[32]={0};
int get_length(char const *arcfile)
{
    int fd,cd,length;
    if((fd=open(arcfile,O_RDONLY))==-1){
        printf("open file error");
        exit(-1);
    }
    snprintf(destfile,sizeof(destfile),"new_%s",arcfile);
    if((cd==open(destfile,O_WRONLY|O_TRUNC|O_CREAT,0666)==-1)){
    }
    length = lseek(fd,0,SEEK_END);
    return length;
}
int copy_file(const char* srcfile,const char* destfile,int start,int length)
{
    int sfd,dfd,ret,count = 0;
    char buff[128] = {0};
    int counts=0;
    if((sfd=open(srcfile,O_RDONLY))==-1){
        printf("open error");
    }
    if((dfd=open(destfile,O_WRONLY))==-1){
        printf("open file error");
    }
    lseek(sfd,start,SEEK_SET);
    lseek(dfd,start,SEEK_SET);
    while (1){
       ret = read(sfd,buff,sizeof(buff));
       if(ret == 0){
            break;
       } 
        count+=ret;
       if(count >= length){
            write(dfd,buff,length-(count-ret));
            break;
       }
       write(dfd,buff,ret);
    }
    return 0;
}
int main(int argc, char const *argv[])
{
    pid_t pid;
    if(argc!=2){
        printf("輸入格式錯(cuò)誤,請重新輸入\n");
        exit(-1);        
    }
    int length = get_length(argv[1]);
    if(length < 0){
        printf("srcfile error\n");
        return -1;
    }
    if((pid=fork())==-1){
        printf("fork error");
        exit(-1);
    }else if(pid == 0){
        copy_file(argv[1],destfile,length/2,length-length/2);
    }else{
        copy_file(argv[1],destfile,0,length/2);
    }
    return 0;
}

三.什么是孤兒進(jìn)程與僵尸進(jìn)程

3.1僵尸進(jìn)程

子進(jìn)程結(jié)束之后,父進(jìn)程沒有為它回收資源,此時(shí)子進(jìn)程就是僵尸進(jìn)程

#include <head.h>
int main(int argc, const char* argv[])
{
    pid_t pid;
    pid = fork();
    if (pid == -1) {
        PRINT_ERR("fork error");
    } else if (pid == 0) {
        //子進(jìn)程
    } else {
        //父進(jìn)程
        while(1);
    }
    return 0;
}

3.2孤兒進(jìn)程

孤兒進(jìn)程:父進(jìn)程死掉之后,子進(jìn)程就是孤兒進(jìn)程,孤兒進(jìn)程被init進(jìn)程收養(yǎng)。

#include <head.h>
int main(int argc, const char* argv[])
{
    pid_t pid;
    pid = fork();
    if (pid == -1) {
        PRINT_ERR("fork error");
    } else if (pid == 0) {
        //子進(jìn)程
        printf("pid = %d\n",getpid());
        while (1);
    } else {
        //父進(jìn)程
    }
    return 0;
}

四,守護(hù)進(jìn)程的創(chuàng)建

4.1守護(hù)進(jìn)程的創(chuàng)建

守護(hù)進(jìn)程:相當(dāng)于系統(tǒng)的服務(wù),隨著系統(tǒng)的啟動(dòng)而運(yùn)行,隨著系統(tǒng)的終止而終止。脫離了某個(gè)終端.

4.2步驟圖

4.3代碼實(shí)現(xiàn)

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define ERROR(msg) do{\
    printf("%s %s %d\n",__FILE__,__func__,__LINE__);\
    printf(msg);\
    exit(-1); \
}while(0)
int main(int argc, char const *argv[])
{
    pid_t pid;
    if ((pid == fork()) == -1){
        ERROR("fork error");
    }else if(pid == 0){
        int fd;
        setsid();
        chdir("/");
        umask(0);
        for(int i = 3; i < getdtablesize(); i++){
            close(i);
        }
        if((fd = open("my.log", O_RDWR, O_APPEND, O_CREAT, 0666)) == -1){
            ERROR("open error");
        }
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        while(1){
            sleep(1);
            printf("我是子進(jìn)程\n");
            fflush(stdout);
        }
    }else{
        printf("父親進(jìn)程已經(jīng)結(jié)束....\n");
        exit(-1);
    }
    return 0;
}

到此這篇關(guān)于C語言超詳細(xì)分析多進(jìn)程的概念與使用的文章就介紹到這了,更多相關(guān)C語言多進(jìn)程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ 壓縮文件及文件夾方法 使用zlib開源庫

    C++ 壓縮文件及文件夾方法 使用zlib開源庫

    下面小編就為大家分享一篇C++ 壓縮文件及文件夾方法 使用zlib開源庫,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • 輸入3個(gè)字符串,將它們按照字母由大到小排序(示例代碼)

    輸入3個(gè)字符串,將它們按照字母由大到小排序(示例代碼)

    我們可以用string方法定義字符串變量。以下是具體實(shí)現(xiàn)代碼。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10
  • 用C語言實(shí)現(xiàn)五子棋游戲

    用C語言實(shí)現(xiàn)五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了用C語言實(shí)現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語言開發(fā)簡易版掃雷小游戲

    C語言開發(fā)簡易版掃雷小游戲

    本文給大家分享的是一個(gè)使用C語言開發(fā)的命令行下的簡易版掃雷小游戲,本身沒有什么太多的技術(shù)含量,只不過是筆者的處女作,所以還是推薦給大家,希望對大家學(xué)習(xí)C能夠有所幫助。
    2015-12-12
  • 淺析C++內(nèi)存布局

    淺析C++內(nèi)存布局

    本文給大家介紹了C++內(nèi)存布局的相關(guān)知識,通過進(jìn)程間通信比線程間通信難也是因?yàn)檫M(jìn)程間的用戶空間是相互隔離的,無法相互訪問,需要通過進(jìn)程間通信方式通信,通過內(nèi)核地址空間
    2021-10-10
  • 學(xué)習(xí)二維動(dòng)態(tài)數(shù)組指針做矩陣運(yùn)算的方法

    學(xué)習(xí)二維動(dòng)態(tài)數(shù)組指針做矩陣運(yùn)算的方法

    這片文章介紹了如何利用二維動(dòng)態(tài)數(shù)組指針做矩陣運(yùn)算,需要的朋友可以參考下
    2015-07-07
  • C語言尋找無向圖兩點(diǎn)間的最短路徑

    C語言尋找無向圖兩點(diǎn)間的最短路徑

    這篇文章主要為大家詳細(xì)介紹了C語言尋找無向圖兩點(diǎn)間的最短路徑,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C語言枚舉類型詳解

    C語言枚舉類型詳解

    這篇文章主要介紹了C語言枚舉類型詳解的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • 基于C語言實(shí)現(xiàn)泛型編程詳解

    基于C語言實(shí)現(xiàn)泛型編程詳解

    對于C而言,想實(shí)現(xiàn)泛型編程并非易事,甚至可以說非常繁瑣,一大堆坑。最主要也沒有現(xiàn)成的輪子可用。本文就來詳細(xì)為大家講講C語言如何實(shí)現(xiàn)泛型編程詳解,需要的可以參考一下
    2022-07-07
  • Qt實(shí)現(xiàn)右擊菜單項(xiàng)

    Qt實(shí)現(xiàn)右擊菜單項(xiàng)

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)右擊菜單項(xiàng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08

最新評論