999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

在LINUX C中以多進程方式實現微型SHELL

2010-01-01 00:00:00張智豐
湖南大學學報·自然科學版 2010年3期

摘要:Linux C為用戶提供了一個強大的編程環境。該文分析并討論了linux OS下微型Shell的基本功能及實現機制,然后運用Linux下的多進程編程技術在Linux C中設計了一個微型Shell,并給出了具體實現辦法。

關鍵詞:Linux C;Linux OS;多進程編程;微型Shell

中圖分類號:TP316文獻標識碼:A文章編號:1009-3044(2010)07-1602-03

Realization of Mini Shell by Multi-Process in Linux C

ZHANG Zhi-feng

(College of Computer Science and Technology, Inner Mongolia University for Nationalities, Tongliao 028043, China)

Abstract: Linux C provides a powerful programming environment for users. The paper analyzes and discusses the mini shell's basic functions and implementation mechanisms under the Linux OS, and then designs a mini-Shell based on multi-process technology in the Linux C, and shows a specific implementation.

Key words: linux C; linux OS; multi-process programming; mini shell

Linux的圖形化環境有很大改進,在X Window系統下,用戶幾乎可以完成所有的操作,只需打開shell提示來完成極少的任務,然而,許多Linux功能在shell提示下要比在圖形化用戶界面GUI下完成得更快[1]。眾所周知,進程是操作系統和并發程序設計的一個非常重要的概念,本文主要應用Linux下的fork( )等系統調用,使用多進程編程技術,設計和實現了一個微型shell(能完成Linux OS標準shell的一部分功能),最后給出了在Linux C下的實現代碼。

1 微型Shell的基本功能及實現機制

1.1 Shell的基本功能

Shell是功能強大的命令解釋器,它不屬于內核部分,而是在核心之外,以用戶態方式運行[2],其最主要的功能是解釋并執行用戶鍵入的命令,實現用戶與Linux核心的接口[3],它是Linux系統的重要組成部分。本文設計的微型shell就是要實現shell的最主要的功能。

1.2 微型Shell的實現機制

系統初啟后,核心為每個終端用戶建立一個進程去執行Shell解釋程序。它的執行過程基本上按如下步驟進行:

1)讀取用戶由鍵盤輸入的命令行,如命令末尾有號(后臺命令符號),則設置后臺執行標識,否則前臺執行。

2)分析命令,以命令名作為文件名,并將其它參數改造為系統調用execvp()內部處理所要求的形式。

3)終端進程調用fork()建立一個子進程,當子進程運行時調用execvp(),從而達到執行用戶提交命令所對應的可執行文件,將它調入內存,執行這個程序(解釋這條命令)。

4)如果命令末尾有號(后臺命令符號),則終端進程不用系統調用wait()(或waitpid())等待,立即發提示符,讓用戶輸入下一個命令,轉1);如果命令末尾沒有號,則終端進程要一直等待。當子進程完成處理后終止,向父進程(終端進程)報告,此時終端進程醒來,在做必要的判別等工作后,終端進程發提示符,讓用戶輸入新的命令,重復上述處理過程。

2 Linux下的多進程編程

欲實現微型shell的設計,要涉及Linux的如下幾個主要的基于進程的系統調用函數:

2.1 fork()函數[4]

fork函數(vfork函數功能與此類似)是用來創建子進程的函數,其函數原型如下所示:

Pid_t fork();

fork函數無參數,當一個進程調用它時,就出現兩個幾乎一模一樣的進程。fork可能有以下三種不同的返回值:

1)在父進程中,fork返回新創建的子進程的進程ID;

2)在子進程中,fork返回0;

3)如果出現錯誤,fork返回一個負值。

2.2exec()函數

調用fork函數后,子進程和父進程幾乎完全一樣,而多數情況下,子進程需要執行與父進程不同的代碼,為此Linux系統提供了exec系統調用,以便用指定的目標程序更換進程的執行映象。Shell進程所創建的子進程正是使用它來執行用戶鍵入的命令。exec函數有6種不同的使用格式,在本文只使用execvp格式,其函數原型如下:

Int execvp(const char *filename,const char *argv[ ]);

其中,參數filename指出可執行目標程序的文件名,它可以通過環境變量PATH來搜索;參數argv是一個字符指針數組,它指出可執行目標程序使用的命令行參數表,按約定第一個字符指針指向與filename相同的字符串,最后一個指針指向一個空字符串,其余的指向該程序執行時所帶的命令行參數。

2.3 wait()函數

進程一旦調用了wait函數(waitpid函數功能與此類似),就立即阻塞自己,由wait自動分析是否當前進程的某個子進程已經退出,如果它找到這樣一個已經變成“僵尸”的子進程,wait就會收集這個子進程的信息,釋放其PCB,并把它徹底銷毀后返回;否則,wait就會一直阻塞下去,直到有一個這樣的子進程出現為止。其函數原型如下:

Pid_t wait(int *status);

參數status是一個指向整數的指針,如果它不為空,子進程的終止狀態字就被存放在該參數所指定的內存位置;如果我們不關心終止狀態字,將該參數置為空即可。

2.4 exit()函數[5]

exit函數是用來終止一個進程的。該函數回收與調用進程相關的各種內核數據結構,把進程狀態置為TASK_ZOMBIE,并把其所有的子進程都托付給init進程,最后調用schedule()函數,選擇一個新的進程來運行。其函數原型如下:

Voidexit(int status);

整型參數satus可以傳遞進程結束時的狀態。一般來說,0表示正常結束;其它數值表示進程非正常結束,出現了錯誤。這里要說明的是,當一個進程已調用exit退出,但其父進程還沒有調用系統調用wait對其進行收集的這段時間里,它會一直保持僵尸狀態。

3 實現微型Shell的具體要求及實現代碼

3.1 具體要求

1)允許用戶輸入一個可執行的程序的名字以及其命令行參數,最多可同時接收5個命令,另外每個命令所帶參數最多不超過10個;

2)可設置命令的前、后臺執行方式,且處理后臺程序時不需要wait;

3)打印提示符;接受和分析命令行(濾去無效的空格、tab符號以及換行符等);

4)能正確執行命令,并且要有出錯處理,最后輸入bye退出。

3.2 Linux C下的實現代碼

#include

#include

#include

#define MAXPARA 10

#define LINE 100

#define CMDLEN 5

char *bye=\"Bye bye!\";

char cmdbuf[CMDLEN][LINE]; /* 用于存放用戶輸入的多條命令 */

int flag[CMDLEN]; /* 用于設置命令后臺運行的標識 */

int main( )

{ int i,n;

While (1)

{printf(\"Hello user\\>\");/* 打印shell提示符 */

for(i=0;i<=4;i++)

{flag[i]=0;cmdbuf[i][0]='\\0';}

if (n= read_analysis_cmd ( )) /* 接收命令 */

execute_cmd ( n ); /*執行命令 */

else

printf(\"read command failed, try again!!!\\");}}

read_analysis_cmd ( )/* 接受和分析命令 */

{char c,*p; int i=0;

p=cmdbuf[0];

while((c=getchar())!='\')

{ if(c==';')

{ *p='\\0';

if(++i==3)

return(i);

p=cmdbuf[i];}

else if(c=='')

flag[i]=1;

else

*p++=c;}

*p='\\0';

return(i); }

execute_cmd ( int n) /*執行命令 */

{int j, stat, pid;

char *argv[MAXPARA], para[LINE];

char c, *parap, **argvp, *p;

for(j=0;j

{ argvp=argv;parap=para;p=cmdbuf[j];

while((c=*p++)!='\\0')

{ while(c==' '|| c=='\')

c=*p++;

if(c=='\\0')

{*argsp++='\\0';

break;}

*argvp++=parap;

while(c!=' 'c!='\'c!='\\0')

{ *parap++=c;

c=*p;

if(c)p++;}

*parap++='\\0';}

*argvp=(char *)0;

if(strcmp(argv[0],bye)==0)

{ printf(\"Bye Bye!\\"); /*輸入bye退出*/

exit(0);}

if((pid=fork())==0)/* 終端進程調用fork( )建立一個子進程 */

{ if(flag[j])setpgrp();/* 重新把調用進程組標識號改為調用進程的進程ID */

execvp(argv[0],argl); /* 調用execvp()執行用戶提交的命令 */

printf(\"Returned from execve.\\");

exit(4);}

else

{ if (!flag[j])

while(wait(stat)!=pid);}/* 不用等待后臺運行的命令 */}}

參考文獻:

[1] 王俊偉,吳俊海.Linux標準教程[M].北京:清華大學出版社,2005.

[2] 鳥哥.鳥哥的Linux私房菜[M].北京:科學出版社,2001.

[3] 陳忠文.Linux操作系統實訓教程[M].北京:中國電力出版社,2006.

[4] 陳莉君,康華.Linux操作系統原理及應用[M].北京:清華大學出版社,2006.

[5] 徐誠,高瑩婷.Linux環境C程序設計[M].北京:清華大學出版社,2010.

主站蜘蛛池模板: 日韩免费毛片视频| 国产精品一区二区不卡的视频| 国产鲁鲁视频在线观看| 亚洲最大福利视频网| 少妇极品熟妇人妻专区视频| 欧美一级一级做性视频| 国产一区二区丝袜高跟鞋| 国产一级在线观看www色| 精品国产美女福到在线不卡f| 国产高清国内精品福利| 婷婷丁香在线观看| 免费一级成人毛片| 国产成人亚洲无码淙合青草| 国产亚洲欧美日韩在线观看一区二区| 亚洲国产91人成在线| 五月天香蕉视频国产亚| 成人在线欧美| 成人在线不卡| 亚洲福利视频网址| 亚洲色无码专线精品观看| 国产福利小视频在线播放观看| 免费激情网址| 久久国产高潮流白浆免费观看| 第一页亚洲| 国产免费网址| 日本不卡免费高清视频| 凹凸精品免费精品视频| 亚洲成人在线免费| 久久永久精品免费视频| 日韩小视频网站hq| 不卡午夜视频| 99精品国产电影| 欧美成一级| 国产大片黄在线观看| 亚洲国产欧美自拍| 国产一区成人| 在线日本国产成人免费的| 精品免费在线视频| 久久综合九九亚洲一区| 国产成人精品一区二区不卡| 精品自窥自偷在线看| 色综合久久无码网| 91精品专区国产盗摄| 国产噜噜噜视频在线观看| 91精品啪在线观看国产91九色| 亚洲国产理论片在线播放| 高清精品美女在线播放| 午夜精品国产自在| 无码丝袜人妻| 亚洲精品制服丝袜二区| 亚洲国产中文在线二区三区免| 国产精品美女在线| 亚洲精品视频免费| 人妻免费无码不卡视频| 欧美h在线观看| 国产毛片不卡| 国产激爽大片高清在线观看| 精品国产成人高清在线| aa级毛片毛片免费观看久| 国产乱人乱偷精品视频a人人澡| 欧美中出一区二区| 欧美色伊人| 亚洲欧美在线综合一区二区三区 | 精品视频第一页| 日韩精品毛片人妻AV不卡| 国产精品浪潮Av| av免费在线观看美女叉开腿| 亚洲欧美不卡中文字幕| 久草性视频| 国产成人精品综合| 91精品国产一区| 欧美综合成人| 亚洲AV无码精品无码久久蜜桃| 天天色天天综合网| 日韩无码视频专区| 伊人成人在线| 国产欧美亚洲精品第3页在线| 尤物成AV人片在线观看| 再看日本中文字幕在线观看| 国产精品流白浆在线观看| 国产97公开成人免费视频| 免费高清毛片|