這是一個可以訓練你EQ的好作業 (拇指
寫到讓我很想砍人
一方面想砍自己太虛,這作業Google那麼久都搞不定
一方面想砍教授,上課細節都沒講,全部都理論最好大家做的出來啦...
都理論的話,看課本就好啦幹麼去上課...
這作業重點筆記
1.EXE家族函數,實測過我會用的就
execvp(argv[0],argv,0);
argv是一個字元指標陣列 char *argv[N]; N隨意,看你想吃幾個參數
0我不知道為啥,我隨便GOOGLE到的,總之測過這樣子可以用
給個例子 假設我要執行ls -l
那麼就
char *a[]={"ls","-l"};
execvp(a[0],a,0);
執行完指令之後,執行的程式會完全取代本身程式
也就是說,不管你在execvp後面擺任何程式碼,
只要execvp執行完之後,後面的程式碼都不會被執行
exe系列函數上課沒講,課本上的資料參考價值->0
網路上的資料也出乎意料之外的少...
(好吧其實是我太嫩ˊ ˋ)
2.pipe
上課有講,課本有寫
總之使用pipe這系統呼叫的時候,會傳回兩個數字,
這兩個數字就是系統成功提供給你的編號,
你必須用 int fd[2]; pipe(&fd[0]);的方式接收
dup這個系統呼叫的功能是,把參數的檔案結構複製到目前第一個為空的pipe
以下是使用範例, 例子使用如何處理 ls | grep .cpp 來講解
程式剛執行的時候是這樣
0.[STD_IN]
1.[STD_OUT]
程式固定會從0讀取,從1寫入,所以pipe的奧義就是要把0跟1換掉
執行pipe之後 會是這樣
0.[STD_IN]
1.[STD_OUT]
2.[read]
3.[write]
先把不必要的管線關掉 對於寫入端 (ls)來說,不需要的管線是read
close(fd[0]); 變成
0.[STD_IN]
1.[STD_OUT]
2.[------]
3.[write]
接下來對於寫入端 (ls) 把STD_OUT換掉
先close(1); 變成
0.[STD_IN]
1.[------]
2.[------]
3.[write]
接下來dup(fd[1]); 變成
0.[STD_IN]
1.[write]
2.[------]
3.[write]
清除掉不要的管線,用close(fd[1]); 變成
0.[STD_IN]
1.[write]
2.[------]
3.[------]
寫入端完成
讀取端套用同樣的邏輯,變成
0.[read]
1.[STD_OUT]
2.[------]
3.[------]
這樣子寫入端的螢幕輸出就會被write到pipe裡面
讀取端的螢幕讀取就會從pipe read
3.fork
這個對於第一次接觸的人來說還蠻深奧的..
因為只是我的筆記,所以我寫簡略一點,詳情自行翻課本QQ
int pid=fork(); 此時程式分裂成兩個完全一樣的程式
母程式得到的回傳值==子程式pid,子程式的到的回傳值==0
檢查自己是主程式還是子程式的方法就是檢查pid
以這次作業來說,架構像是這樣
pid1=fork();
if(pid1==0)
{
這邊是子程式1該做的事情
}
pid2=fork();
if(pid2==0)
{
這邊是子程式2該做的事情
}
以圖案表示的話
========fork===================fork=========================
|-----執行ls |----執行grep
4.fork後,主程式要等待子程序執行完畢
waitpid(-1,0,0),參數意義我懶得查了...
5.字串處理部份
C的字串處理只有一個囧字可以形容...
如果指令是 char *a="ls | grep .cpp"; 的話
可以用strtok(a," ");的方式分段
strtok回傳的是char*型態
第一次執行的時候,他會把第一個" "之前的字元指標開始處傳回
第二次以後需要執行strtok(NULL," "); 他會繼續把剩下的字串重新分割
如果找不到的話 回傳NULL
給個範例
char *argv1[11];
argv1[0]=strtok(cmd1," ");
for(i=1;i<=10;i++)argv1[i]=strtok(NULL," ");
假設cmd1是"ls | grep .cpp"
那麼陣列argv1會分別指向
ls,|,grep,cpp,NULL,NULL,NULL,NULL,NULL,NULL,NULL
---
如果很閒的話,寫這種教授不給資料,全部自己Google的作業是很好玩啦
只是現在我會覺得好花時間..
留言列表