午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

學(xué)習(xí)linux C編程實戰(zhàn)-----linux進(jìn)程控制

 happy123god 2012-04-23




Linux進(jìn)程

進(jìn)程是操作系統(tǒng)資源管理的最小單位。是一個動態(tài)的實體,是程序的一次執(zhí)行過程。
進(jìn)程是動態(tài)的,程序是靜態(tài)的;
為了在同一時間內(nèi)能執(zhí)行更多的任務(wù),進(jìn)程內(nèi)部又可劃分了許多的線程。
線程在進(jìn)程內(nèi)部,是比進(jìn)程更小的能獨立運行的基本單位。線程基本上不擁有系統(tǒng)資源,它與同屬于一個進(jìn)程的其他線程共享進(jìn)程擁有的全部資源。
linux下可通過命令ps或pstree查看當(dāng)前系統(tǒng)的進(jìn)程。

進(jìn)程的標(biāo)識
每個進(jìn)程都是通過唯一 的進(jìn)程ID標(biāo)識的。非負(fù)數(shù),每個進(jìn)程除了進(jìn)程ID外還有其它的標(biāo)識符信息,都可以通過相應(yīng)的函數(shù)獲得。這些函數(shù)的聲明在 unistd.h 頭文件中。
 
獲取進(jìn)程各種標(biāo)識符的函數(shù)


pid_t getpid(id)      //獲得進(jìn)程ID
pid_t getppid(id)    //獲得進(jìn)程父進(jìn)程ID
pid_t getuid()        //獲得進(jìn)程的實際用戶ID
pid_t geteuid()        //獲得進(jìn)程的有效用戶ID    
pid_t getgid()        //獲得進(jìn)程的實際組ID
pid_t getegid(id)    //獲得進(jìn)程的有效組ID


實際用戶ID(uid):標(biāo)識運行該進(jìn)程的用戶。
有效用戶ID(euid):標(biāo)識以什么用戶身份來運行進(jìn)程。如:普通用戶A,運行了個程序,是以root身份來運行的,這個程序運行時就具有root權(quán)限。此時實際用戶ID是A用戶的ID,而有效用戶ID是root用戶ID。
實際組ID(gid):實際用戶所屬的組的組ID。
有效組ID(egid):有效組ID是有效用戶所屬的組的組ID。

linux進(jìn)程狀態(tài)
運行狀態(tài)R(runnbale)
可中斷等待狀態(tài)S(sleeping)
不可中斷等待狀態(tài)D(uninterruptible sleep)
僵死狀態(tài)Z(zombile)
停止?fàn)顟B(tài)T(traced or stopped)
<(高優(yōu)先級進(jìn)程),N(低優(yōu)先級進(jìn)程),L(內(nèi)存鎖頁面,即頁面不可以被換出內(nèi)存),s(該進(jìn)程為會話首進(jìn)程),l(多線程進(jìn)程),+(進(jìn)程位于前臺進(jìn)程組)。

進(jìn)程控制


主要的系統(tǒng)調(diào)用有
fork:用于創(chuàng)建一個新進(jìn)程
exit:用于終止一個應(yīng)用程序。
exec:用于執(zhí)行一個應(yīng)用程序。
wait:將父進(jìn)程掛起,等待子進(jìn)程終止。
getpid:獲取當(dāng)前進(jìn)程的進(jìn)程ID。
nice:改變進(jìn)程的優(yōu)先級。

進(jìn)程的創(chuàng)建兩種方式
一、由操作系統(tǒng)創(chuàng)建。平等的
二、由父進(jìn)程創(chuàng)建。繼承的

系統(tǒng)調(diào)用fork是創(chuàng)建一個新進(jìn)程的唯一方法,除了極少數(shù)以特殊方式創(chuàng)建的進(jìn)程。如:init

創(chuàng)建一個子進(jìn)程之后,父進(jìn)程和子進(jìn)程爭奪CPU,搶到的執(zhí)行,另一個掛起等待。
如果想要父進(jìn)程等待子進(jìn)程執(zhí)行完畢以后在繼續(xù)執(zhí)行,可以在fork操作之后調(diào)用wait或waitpid。

#inlcude<sys/types.h>
#inlcude<unistd.h>
pid_t fork(void);

fork函數(shù)調(diào)用一次返回兩次,父進(jìn)程返回值為新創(chuàng)建的子進(jìn)程的進(jìn)程ID  子進(jìn)程I返回值為0,


fork.c

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
    pid_t pid;
    printf("Process Creation Study\n");
    pid=fork();
    switch(pid)
    {
        case 0:
            printf("Child process is running ,Current Pid is %d,ParentPid is %d\n",pid,getppid());
            break;
        case -1:
            perror("Process creation failed\n");
            break;
        default:
            printf("Patent process is running , ChildPid is %d,Parentpid is %d\n",pid,getpid());
            break;
    }
    exit(0);
}


fork2.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
    pid_t pid;
    char *msg;
    int k;
    printf("Process Creation Study\n");
    pid=fork();
    switch(pid)
    {
        case 0:
            msg="Child process is running ";
            k=3;
            break;
        case -1:
            preeor("Process creation failed\n");
            break;
        default:
            msg="Parent process is running ";
            k=5;
            break;
    }
    while(k>0)
    {
        puts(msg);
        sleep(1);
        k--;
    }
    exit(0);
}    

孤兒進(jìn)程
如果一個子進(jìn)程的父進(jìn)程先于子進(jìn)程結(jié)束,子進(jìn)程就成為一個孤兒進(jìn)程,它有init進(jìn)程收養(yǎng),成為init進(jìn)程的子進(jìn)程。
fork3.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(void)
{
    pid_t pid;
    pid=fork();
    switch(pid)
    {
        case 0:
            while(1)
            {
                printf("A background process,PID:%d\n,Parent ID:%d\n",getpid(),getppid());
                sleep(3);
            }
        case -1:
            perror("Process creation failed\n");
            exit(-1);
        default:
            printf("I am parent process ,my pid is %d\n",getpid());
            exit(0);
    }
    return 0;
}


vfork函數(shù)

也可以創(chuàng)建一個新進(jìn)程,于fork的異同
1、都是調(diào)用一次返回兩次。
2、使用fork創(chuàng)建一個子進(jìn)程時,子進(jìn)程只是完全復(fù)制父進(jìn)程的資源。這樣得到的子進(jìn)程獨立于父進(jìn)程,有良好的并發(fā)性。而使用vfork創(chuàng)建的子進(jìn)程時,操作系統(tǒng)并不將父進(jìn)程的地址空間完全復(fù)制到子進(jìn)程,用vfork創(chuàng)建的子進(jìn)程共享父進(jìn)程的地址空間,子進(jìn)程的運行完全在父進(jìn)程地址空間上。
子進(jìn)程對該地址空間中任何數(shù)據(jù)的修改同樣為父進(jìn)程所見。
3、使用fork創(chuàng)建一個子進(jìn)程是,是那個進(jìn)程先運行取決于系統(tǒng)的調(diào)度算法。而vfork一個進(jìn)程時,vfork保證子進(jìn)程先運行,當(dāng)它調(diào)用exec或exit之后,父進(jìn)程才可能被調(diào)度運行。如果在調(diào)用exec或exit之前子進(jìn)程要依賴父進(jìn)程的某個行為,就會導(dǎo)致死鎖。

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

守護(hù)進(jìn)程(daemon)指在后臺運行的沒有控制終端與之相連的進(jìn)程。獨立于控制終端,通常周期性的執(zhí)行某種任務(wù)。linux中的大多數(shù)服務(wù)器就是用守護(hù)進(jìn)程的方式實現(xiàn)的。在后臺運行。

啟動方式:
linux系統(tǒng)啟動時從啟動腳本/etc/rc.d中啟動
有作業(yè)規(guī)劃進(jìn)程crond啟動
由用戶終端執(zhí)行


daemon.c
#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<sys/param.h>
#include<sys/stat.h>
#include<time.h>
#include<syslog.h>
int init_datmon(void)
{
    int pid;
    int i;
    ..................
    .......
}



進(jìn)程退出
(1)正常退出
在main函數(shù)中執(zhí)行return。
調(diào)用exit函數(shù)。
調(diào)用_exit函數(shù)。
(2)異常退出
調(diào)用about函數(shù)。
進(jìn)程收到某個信號,而該信號是程序終止。

不管那種退出方式,最終都會執(zhí)行內(nèi)核中的同一段代碼。這段代碼用來關(guān)閉進(jìn)程所有已打開的文件描述符,釋放它所有占用的內(nèi)存和其他資源。

各種退出方式的比較:
a、exit和return的區(qū)別:exit是一個函數(shù),有參數(shù);而return是函數(shù)執(zhí)行完后的返回。exit把控制權(quán)交給系統(tǒng),而return將控制權(quán)交給調(diào)用函數(shù)。
b、exit和about的區(qū)別:exit是正常終止進(jìn)程,而about是異常終止。
c、exit(int exit_code):exit中的參數(shù)exit_code為0代表進(jìn)程正常終止,若為其他值表示程序執(zhí)行過程中有錯誤發(fā)生
d、exit()和_exit()的區(qū)別:exit在頭文件stdlib.h中聲明,而_exit()聲明在頭文件unistd.h中
兩個函數(shù)都能正常終止進(jìn)程,但是_exit()會執(zhí)行后立即返回給內(nèi)核,而exit()要先執(zhí)行一些清除操作,然后將控制權(quán)交給內(nèi)核。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多