進(jìn)程
* 進(jìn)程 程序的一次動態(tài)執(zhí)行過程
進(jìn)程生命周期:
- 創(chuàng)建:創(chuàng)建虛擬地址空間茴恰、地址空間分段吐限,創(chuàng)建task_struct結(jié)構(gòu)(PCB進(jìn)程控制塊)
- 調(diào)度:內(nèi)核管理task_struct結(jié)構(gòu)組成的鏈表,根據(jù)優(yōu)先級和進(jìn)程屬性分配時間片
- 執(zhí)行:進(jìn)程獲得時間片到cpu中執(zhí)行
- 消亡:進(jìn)程結(jié)束,回收虛擬地址空間,由父進(jìn)程回收task_struct結(jié)構(gòu)杂伟。
虛擬地址空間分段:
- stack:棧區(qū),存放局部變量仍翰、函數(shù)傳參赫粥、返回地址
- 不要進(jìn)行太深的遞歸防止棧溢出。
- heap:堆區(qū)予借,用來給malloc使用的空間
- 使用完成記得free防止內(nèi)存泄露
- .bss:未初始化的全局變量/靜態(tài)變量static(作用域)
- .data:已初始化的全局/靜態(tài)變量
- .text:代碼越平、常量
* task_struct:pid進(jìn)程號 ppid父進(jìn)程號 用到的資源 內(nèi)存映射表 打開的文件
程序和進(jìn)程有什么區(qū)別 ?
- 程序是靜態(tài)的灵迫,是一個文件
- 進(jìn)程是動態(tài)的一個執(zhí)行過程秦叛,包括創(chuàng)建、調(diào)度瀑粥、執(zhí)行挣跋、消亡整個生命周期。
* ps 查看當(dāng)前終端的進(jìn)程 任意的命令也是一個進(jìn)程
- ps -ef 查看更多進(jìn)程信息狞换,可以查看到父進(jìn)程ID浆劲,tty為?表示與終端無關(guān)哀澈。
- ps -aux可以查看進(jìn)程狀態(tài)
- ps -axj可以查看到會話組
- top可以動態(tài)查看進(jìn)程狀態(tài)包括優(yōu)先級 空格刷新 q退出
* pstree 樹形查看進(jìn)程關(guān)系,init是所有進(jìn)程的根度气,進(jìn)程號為1
* 進(jìn)程組:為了統(tǒng)一管理一些進(jìn)程分的組
* 會話組:比進(jìn)程組更大的單位割按,可以包含多個進(jìn)程組
進(jìn)程分類:
交互進(jìn)程:前臺進(jìn)程(既可以輸入、也可以輸出)磷籍、后臺(只能輸出)
-
后臺進(jìn)程產(chǎn)生:./a.out &
- ctrl+z 暫停适荣,bg 放到后臺
- fg 可以喚到前臺
批處理進(jìn)程
守護進(jìn)程
-
進(jìn)程狀態(tài):
S:睡眠/等待態(tài)
T:停止態(tài)(暫停)
R:運行態(tài)
Z:僵尸態(tài),父進(jìn)程沒有回收子進(jìn)程資源
+表示前臺 s會話組長 l多線程 <優(yōu)先級比較高 N表示優(yōu)先級比較低
* kill 給進(jìn)程發(fā)送信號 -l可以查看所有的信號 -9強制結(jié)束一個進(jìn)程
* 運行前指定優(yōu)先級 nice ./a.out 10
* 運行時改變優(yōu)先級 renice 5 pid
* 父進(jìn)程退出院领,子進(jìn)程會成為孤兒進(jìn)程弛矛,孤兒進(jìn)程由init接管
* fork();創(chuàng)建一個子進(jìn)程,在父進(jìn)程中返回子進(jìn)程的pid比然,在子進(jìn)程中返回0丈氓。
* fork之前的內(nèi)容拿到結(jié)果(繼承),之后的內(nèi)容原樣復(fù)制。
* fork之前打開的文件万俗,復(fù)制時會延續(xù)之前的結(jié)構(gòu)湾笛,會使用同一個文件指針,父子進(jìn)程操作文件會互相造成影響闰歪。
* getpid獲得自己的pid
* getppid獲得父進(jìn)程的pid
execl :
- execl(可執(zhí)行文件嚎研,執(zhí)行方式,其他參數(shù)库倘,以NULL結(jié)尾);
- 替換當(dāng)前地址空間內(nèi)容临扮,執(zhí)行新的可執(zhí)行文件。
- ...可變長度傳參教翩,以NULL結(jié)尾杆勇。
_exit :
- _exit(int status);
- 不清理緩沖區(qū),立即退出當(dāng)前進(jìn)程迂曲。status返回給父進(jìn)程靶橱,父進(jìn)程通過wait一族函數(shù)回收。
* exit() ; 退出進(jìn)程時清理緩沖區(qū)路捧。
* wait() ; 阻塞等待子進(jìn)程改變狀態(tài)关霸,子進(jìn)程改變狀態(tài)之后wait變成非阻塞。
waitpid(pid,status,options);
- pid: <-1:等待組ID為-pid的子進(jìn)程
- -1:等待任意子進(jìn)程
- 0:等待當(dāng)前進(jìn)程組的子進(jìn)程
- >0:等待指定的子進(jìn)程
- options:
- 0:阻塞等待
- WNOHANG非阻塞杰扫,并且沒有子進(jìn)程退出队寇,直接返回0
練習(xí) :
通過fork創(chuàng)建一個子進(jìn)程,父進(jìn)程復(fù)制1.txt的前一半章姓,子進(jìn)程復(fù)制1.txt的后一半佳遣,然后寫入到2.txt。
/************************************************************************
> File Name: homework.c
> Author: Lin
> Mail: linbb@farsight.cn
> Created Time: 2016年12月01日 星期四 09時11分48秒
*******************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SIZE 64
int main(int argc, const char *argv[])
{
pid_t p;
char buf[SIZE];
int fp1,fp2;
long len,sum = 0,n;
fp1 = open("1.txt",O_RDONLY|O_EXCL);
if(-1 == fp1)
{
perror("open1");
return -1;
}
fp2 = open("2.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);
if(-1 == fp2)
{
perror("open2");
return -1;
}
len = lseek(fp1,0,SEEK_END);
if(-1 == len)
{
perror("lseek 1");
return -1;
}
len /= 2;
p = fork();
if(-1 == p)
{
perror("fork");
return -1;
}
if(p == 0)
{
if(-1 == lseek(fp1,len,SEEK_SET))
{
perror("lseek 2");
return -1;
}
if(-1 == lseek(fp2,len,SEEK_SET))
{
perror("lseek 3");
return -1;
}
while(1)
{
n = read(fp1,buf,SIZE);
// printf("child:n = %ld\n",n);
if(-1 == n)
{
perror("read");
return -1;
}
if(0 == n)
break;
write(fp2,buf,n);
}
}else
{
if(-1 == close(fp1))
{
perror("close 1");
return -1;
}
if(-1 == close(fp2))
{
perror("close 2");
return -1;
}
fp1 = open("1.txt",O_RDONLY|O_EXCL);
if(-1 == fp1)
{
perror("open1");
return -1;
}
fp2 = open("2.txt",O_WRONLY);
if(-1 == fp2)
{
perror("open2");
return -1;
}
if(-1 == lseek(fp1,0,SEEK_SET))
{
perror("lseek 4");
return -1;
}
if(-1 == lseek(fp2,0,SEEK_SET))
{
perror("lseek 5");
return -1;
}
while(1)
{
n = read(fp1,buf,SIZE);
sum += n;
// printf("father:n = %ld,sum = %ld,len = %ld\n",n,sum,len);
if(-1 == n)
{
perror("read");
return -1;
}
if(sum > len)
{
write(fp2,buf,n - (sum - len));
break;
}
write(fp2,buf,n);
}
}
if(-1 == close(fp1))
{
perror("close 1");
return -1;
}
if(-1 == close(fp2))
{
perror("close 2");
return -1;
}
return 0;
}