熊博安 教授.

Slides:



Advertisements
Similar presentations
Linux 环境及 Shell 程序 操作系统实验 1. 二、 Shell 编程与进程通信 常用 shell 命令 文件及文件属性操作 ls 、 cp 、 mv 、 rm ln 、 ln –s 、 chmod 、 groupadd 、 useradd 输入输出操作 echo 、 cat >> 、
Advertisements

进 程. “ 程序 ” 和 “ 进程 ” 进程是 OS 对 CPU 执行的程序的运行过程的一种抽象。进程有自 己的生命周期,它由于任务的启动而创建,随着任务的完成(或 终止)而消亡,它所占用的资源也随着进程的终止而释放。 Linux 内核中通常把进程称为任务,每个进程主要通过一个称为进程描 述符(
第一單元 建立java 程式.
計算機程式語言實習課.
第1单元 操作系统概论 第一节 绪论 操作系统定义.
行程(process).
第一章 C语言概述 计算机公共教学部.
基于操作系统的编程复习 张玉宏
TQC+ JAVA全國教師研習會 PLWeb 程式設計練習平台 簡介.
產生新的程序:fork() (2/4) fork()回傳時,若成功 若fork()失敗,則回傳-1 新子程序將被加入於系統中
Hadoop 單機設定與啟動 step 1. 設定登入免密碼 step 2. 安裝java step 3. 下載安裝Hadoop
Chapter 5 迴圈.
南京天石软件技术有限公司 陈锺 (QQ: Solaris 10 C编程 南京天石软件技术有限公司 陈锺 (QQ:
臺北市立大學 資訊科學系(含碩士班) 賴阿福
程式設計概論 1.1 程式設計概論 程式語言的演進 物件導向程式 程式開發流程 1.2 C++開發工具
Chapter 1 用VC++撰寫程式 Text book: Ivor Horton.
chapter 1-Introduction
system(const char *string)
第一篇 Unix/Linux 操作介面 第 1 章 Unix/Linux 系統概論 第 2 章 開始使用 Unix/Linux
JDK 安裝教學 (for Win7) Soochow University
中国科学技术大学计算机系 陈香兰(0512- ) Spring 2011
簡易 Visual Studio 2010 C++ 使用手冊
編譯環境介紹.
Linux Programming – Process & Signal
第7章 Linux环境编程.
Function.
进程及进程管理 第4章 进程及进程管理.
实践演练 广州创龙电子科技有限公司 01 广州创龙电子科技有限公司
安裝JDK 安裝Eclipse Eclipse 中文化
作業系統實習課(一) -處理程序相關指令介紹-
进程操作.
Process management(程序管理)
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A.
Linux操作系统分析 中国科学技术大学计算机系 陈香兰(0512- )
3 S7-200可编程控制器 使用入门 2019/2/17.
第一單元 建立java 程式.
实验一、进程控制 一、实验目的 1、加深对进程的理解,进一步认识并发执行的实质; 2、分析进程争用资源现象,学习解决进程互斥的方法;
VS.NET 2003 IDE.
第2章 进程和线程 内容提要: 2.1 进 程 概 念 2.2 进程的状态和组成 2.3 进 程 管 理 2.4 线 程.
Linux Debugging ls,ps,top,etc. printk() /proc i386提供的调试机制(断点,信号,单步执行)
C++ 程式設計 基礎篇 張啟中 Chang Chi-Chung.
GUI Title and GUI Status
3.5 线程 问题的提出 进程的引入使操作系统得以完成对并发执行的多道程序动态特征的描述和资源共享的管理,因而进程既是调度的基本单位又是资源分配的基本单位。进程所具有的这两个特点构成了程序并发执行的基础,但同时又导致进程切换过程中由于进程映像过大而带来的时空开销。因此,如果系统中创建的进程过多,或进程切换的频率过高,则会使系统效率下降,限制了并发度的进一步提高。
VS.NET 2003 IDE.
FTP使用教學 簡介: 軟體名稱:FileZilla 軟體性質:Freeware 版本: 繁體中文版
C qsort.
DRC with Calibre 課程名稱:VLSI 報告人:黃家洋 日期: 改版(蔡秉均) 1.
Video 影像 (VideoPlayer 影像播放器、Camcorder 錄影機) 靜宜大學資管系 楊子青
Pthread.
1.3操作系统提供的服务和用户接口 操作系统提供的用户接口 程序接口与系统调用 操作接口与系统程序
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A Lab7.
ZigBee PRO教學系統 CC2530 實驗.
 隐式欧拉法 /* implicit Euler method */
2018 Operating Systems 作業系統實習 助教:林欣穎 實驗室:720A.
Computer Science & Information Management
实验二:添加Linux系统调用及熟悉常见系统调用
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A Lab4.
Arguments to the main Function and Final Project
作業一: 安裝Linux於btrfs上 中正大學 作業系統實驗室 指導教授:羅習五
安裝JDK 配置windows win7 環境變數
作業系統實習課(二) -Scheduler-Related System Calls-
第6章 嵌入式软件开发基础.
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
Chapter 4 Multi-Threads (多執行緒).
2019 Operating Systems 作業系統實習 助教:林欣穎 實驗室:720A Lab7.
Unix指令4-文字編輯與程式撰寫.
Develop and Build Drives by Visual C++ IDE
JUDGE GIRL 使用介紹 & 常見問題 TAs :
《操作系统设计与实现》 Linux系统编程.
ABAP Basic Concept (2) 運算子 控制式與迴圈 Subroutines Event Block
Presentation transcript:

熊博安 教授

Chapter 9 程序控制

單元介紹 程序 產生新的程序:fork() 等待子程序狀態轉換:wait() 將新的程式載入程序中:exec

程序控制 Chapter 9 9.1 程序 9.2 產生新的程序:fork() 9.3 等待子程序狀態轉換:wait() 9.4 將新的程式載入程序中:exec

單元簡介 本單元主要介紹Linux作業系統中最基本執行單元,程序 (Process)或者任務 (Task)的概念並且回覆以下的問題: 如何產生新的程序? 原父程序與新子程序之間的關係為何?有無先後執行順序?如何控 制先後順序? 如何載入新的程式執行檔?

何謂程序?程序(1/4) 電腦中的任何應用,例如遊戲、編輯器、瀏覽器等均需要 作業系統中任何工作均以程序(Process)方式存在系統中 先將程式原始碼撰寫完成 (Source Program) 編譯成電腦可以看得懂得執行檔 (Executable Binary Program) 存放於電腦的硬碟中 需要執行任務時,啟動執行檔 (Start Execution) 例如:將一個系統畫面上的圖示,用滑鼠點兩下即可啟動程式 作業系統中任何工作均以程序(Process)方式存在系統中 程式 (Program) 靜態存放於儲存媒體的【執行檔】 程序 (Process) 動態可完成計算與資料傳輸任務的【基本執行單元】

程序ID (Process ID, PID) 程序(2/4) 當一個新的程序誕生時,系統會給予這個程 序一個身份辨識碼(ID),即 程序ID (Process ID, PID) 數值:PID為一正整數 (1, 2, 3, …) 唯一性:每個程序的PID均為系統中唯一的 (unique) 生活例子:每位國家公民都會有一組唯一的 身分證字號 依據啟發程序的使用者與相關屬性關係,給 予程序一組有效的權限設定

/proc 程序(3/4) /proc 是一個虛擬檔案系統,裏面的檔案除了kcore外,其他檔案大小均為0 /proc包含執行期系統資訊(runtime system information) 系統記憶體內容、載入之裝置、硬體組態等

/proc 程序(4/4) /proc可以用來查詢系統動態資訊及設定系統動態參數 很多系統工具均參考此資料夾內容 lsmod 等同於 cat /proc/modules lspci 等同於 cat /proc/pci 可使用/usr/bin/procinfo工具程式瞭解系統資訊 例如:能源管理、裝置、CPU資訊、驅動程式、資安、檔案系統、中斷、I/O阜、 核心資訊等 可查看/proc/PID (PID為某個程序的ID)資料夾,瞭解某程序的相關資訊 例如:環境變數、工作資料夾、執行檔、開啟的檔案、程序狀態等

程序控制 Chapter 9 9.1 程序 9.2 產生新的程序:fork() 9.3 等待子程序狀態轉換:wait() 9.4 將新的程式載入程序中:exec

產生新的程序:fork() (1/4) POSIX 作業系統的標準中,新的程序均需藉由呼叫fork()函數而產生 fork()函數雛型 父程序(parent process):呼叫fork()函數的程序。 子程序(child process):fork()回傳後,新產生的程序。 fork()函數雛型 #include <unistd.h> pid_t fork(void); fork()功用 分工合作:父程序與一個以上的子程序,共同分工合作完成任務。 執行新程式:由子程序執行新的程式,父程序可選擇等待或不等子程序完成執行程 式。

產生新的程序:fork() (2/4) fork()回傳時,若成功 若fork()失敗,則回傳-1 新子程序將被加入於系統中 子程序與父程序擁有一模一樣的記憶體內容 程式機器碼、程序所有資料、程序堆疊(stack)、程序heap、環境變數等 子程序與父程序不同的屬性有:PID、資源使用率、CPU計時器、待處理號誌、應用程式 計時器 (重設) fork()回傳值 在父程序,回傳值為新子程序的PID 在子程序,回傳值為0 可做為分工合作時,不同的程式碼段落 父程序程式碼 vs. 子程序的程式碼 (在同一支程式內) 若fork()失敗,則回傳-1

若fork()成功,父程序與子程序均從此敘述繼續執行 fork() 程式範例 fork() (3/4) 若fork()成功,父程序與子程序均從此敘述繼續執行 #include <stdio.h> #include <unistd.h> int main() { int var = 0; pid_t pid; pid = fork(); printf(“%d”, var); if(pid == 0) { /* child 執行 */ var = 1; } else if (pid > 0) { /* parent 執行 */ var = 2; } printf(“%d”, var) return 0;

fork()程式範例 fork()(4/4) 利用fork()的回傳值 (亦即pid)進行父程序與子程序各自需要完成任務的 程式碼區分 各程序的執行結果: 父程序:02 子程序:01 然而,系統並沒有限制兩個程序的執行順序 若fork()成功,執行結果可能為:0012, 0021, 0102, 或 0201 若fork()失敗,執行結果為:00

Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan Lab 1: debugging fork() Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan

Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan Lab 1: debugging fork() When a program forks, gdb will continue to debug the parent process and the child process will run unimpeded. If you have set a breakpoint in any code which the child then executes, the child will get a SIGTRAP signal which (unless it catches the signal) will cause it to terminate. debugging the child process using touch commend (hint: put sleep after fork) debug child process instead of parent process (using “set follow-fork-mode child” http://sourceware.org/gdb/onlinedocs/gdb/Forks.html http://www.cnblogs.com/zhenjing/archive/2011/06/01/gdb_fork.html Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan

Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan lab 1: debugging fork() $gcc -g lab1-1.c $gdb a.out (gdb)b main /*set a breakpoint*/ (gdb)r /*run*/ (gdb)n /*next*/ (gdb)s /*step into*/ (gdb)p glob /*print*/ (gdb)display glob (gdb)c /*continue*/ Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan

Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan lab 1: debugging fork() $gcc -g lab1-1.c $gdb a.out (gdb)l main /*list 10 lines of source code of main function*/ (gdb)b main /*set a breakpoint*/ (gdb)r /*run*/ (gdb)n /*next*/ (gdb)p globvar /*print*/ (gdb)c /*continue*/ (gdb)set globvar=11 /*Setting Variables*/ http://betterexplained.com/articles/debugging-with-gdb/ Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan

Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan lab 1: debugging fork() (gdb) set follow-fork-mode child (gdb) n ... (gdb) p pid /*child OR parent?*/ Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan

Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan lab 1: debugging fork() (gdb) set follow-fork-mode child (gdb) n ... (gdb) p pid /*child OR parent?*/ Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan

Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan lab 1: debugging fork() /*modify your program like... waiting = 1; if (fork()==0) while(waiting); ... */ $sudo gdb a.out (gdb) attach pid (gdb) set waiting=0 /*continue*/ Slides©2006 Pao-Ann Hsiung, National Chung Cheng University, Taiwan

程序控制 Chapter 9 9.1 程序 9.2 產生新的程序:fork() 9.3 等待子程序狀態轉換:wait() 9.4 將新的程式載入程序中:exec

等待子程序狀態轉換:wait() (1/7) 當子程序狀態轉換時,父程序負責處理其狀態。 子程序結束:父程序等待後,可使子程序所佔用的資源釋放還給系統。 若父程序沒有等帶子程序,子程序會變成殭屍程序(zombie process)。 子程序收到號誌後暫停運行 (stopped)。 子程序收到號誌後恢復運行 (resumed)。

< -1 or > 0: 指定子程序 (取絕對值) wait() (2/7) -函數雛型 #include <sys/types.h> #include <sys/wait.h> pid_t wait(int *status); /* 等待任何一個子程序結束 */ pid_t waitpid(pid_t pid, int *status, int options); /* 等待子程序 結束 */ int waitid(idtype_t idtype, id_t id, siginfo_t * infop, int options); /* 等待子程序的特定狀態轉換 */ 若非NULL,儲存子程序狀態 < -1 or > 0: 指定子程序 (取絕對值) -1: 任何子程序 0: 同群組的任何子程序 OR of { WNOHANG (若沒有子程序結束立刻回傳), WUNTRACED (回傳,若有子程序被暫停), WCONTINUED (回傳,若有子程序被恢復) }

等待子程序狀態轉換:wait() (3/7) 檢查子程序狀態可使用表中的MACROS,但是直接使用整數值 status,而不是指標。 描述 WIFEXITED(status) TRUE,若子程序正常結束 WEXITSTATUS(status) 子程序結束狀態 (exit status) WIFSIGNALED(status) TRUE,若子程序被號誌終止 WTERMSIG(status) 子程序被號誌終止的號誌編號 (signal number) WCOREDUMP(status) TRUE,若子程序有產生CORE檔 WIFSTOPPED(status) TRUE,若子程序被號誌暫停 WSTOPSIG(status) 子程序被號誌暫停的號誌編號 (signal number) WIFCONTINUED(status) TRUE,若子程序收到SIGCONT號誌而恢復運行

等待子程序狀態轉換:wait() (4/7) waitid() 的參數:idtype, id, options idtype 參數 描述 P_PID 子程序PID需要符合 id 參數值 P_PGID 子程序群組ID需要符合 id 參數值 P_ALL 任何子程序 (id 將被忽略) options 參數 描述 WEXITED 等待子程序結束 WSTOPPED 等待子程序因為收到號誌而被暫停 WCONTINUED 等待暫停的子程序因為收到SIGCONT號誌,而恢復運行

範例執行結果 wait()(5/7) $ ./a.out & Child PID is 32360 [1] 32359 $ kill -STOP 32360 stopped by signal 19 $ kill -CONT 32360 continued $ kill -TERM 32360 killed by signal 15 [1]+ Done ./a.out $

範例程式碼 wait()(6/7) #include <sys/wait.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> Int main(int argc, char *argv[]) { pid_t cpid, w; int status; cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (cpid == 0) { /* Code executed by child */ printf("Child PID is %ld\n", (long) getpid()); if (argc == 1) pause(); /* Wait for signals */ _exit(atoi(argv[1])); }

範例程式碼 wait()(7/7) else { /* Code executed by parent */ do { w = waitpid(cpid, &status, WUNTRACED | WCONTINUED); if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { printf("exited, status=%d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("killed by signal %d\n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("stopped by signal %d\n", WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("continued\n"); } } while (!WIFEXITED(status) && !WIFSIGNALED(status)); exit(EXIT_SUCCESS);

本小節課程結束

程序控制 Chapter 9 9.1 程序 9.2 產生新的程序:fork() 9.3 等待子程序狀態轉換:wait() 9.4 將新的程式載入程序中:exec

將新的程式載入程序中:exec (1/5) 父程序呼叫fork()後所產生的子 程序,一開始擁有與父程序一 模一樣的程式碼。

將新的程式載入程序中:exec (2/5) exec若執行成功,原本記憶體的程序資料(機器碼、資料、堆疊、heap、 環境)均被新的程式資料取代。 因為原本呼叫exec的程式已經不存在,所以exec就不會回傳。 exec若執行不成功,函數將回傳-1到原本的程式並且會設定errno全域 變數記錄錯誤情況。

載入程式的exec函數有六個版本,其雛型為exec (3/5) #include <unistd.h> /* 清單版本 list (l) versions */ int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg,..., char*const envp[]); /* 向量版本 vector (v) versions */ int execv(const char *path, char *const argv[]); int execvp(const char *file, char *const argv[]); int execvpe(const char *path, char*const argv[],char*const envp[]); p: (path)不指定路徑,使用系統環境變數PATH。 e: (environment)指定環境變數陣列,不參考系統environ變數。

將新的程式載入程序中:exec (4/5) List/vector list vector 參考PATH? NO YES 參考environ? 函數 execl() execlp() execle() execv() execvp() execvpe() 基本上,上述函數都會用到Linux系統呼叫(system call) execve() 上述表中,根據應用程式的需求可以選用不同的exec函數,例如: 執行程式時,需要特定路徑及特定環境時,就選用execle()。 執行程式時,參考系統路徑PATH、系統環境environ,則可選用execlp()或execvp()。

範例程式 exec (5/5) 不參考PATH,所以需要寫出絕對路徑 “/bin/ls” 。 main() { pid_t pid; char *const parmList[] = {"/bin/ls", "-l", "/u/userid/dirname", NULL}; if ((pid = fork()) == -1) perror("fork error"); else if (pid == 0) { /* child */ execv("/bin/ls", parmList); printf("Return not expected. Must be an execv error.\n"); } 不參考PATH,所以需要寫出絕對路徑 “/bin/ls” 。 參考系統環境變數 environ,所以並沒有另外輸入。 程式的參數有事先放在一個陣列中(parmlist[]) 。

參考資料 Simply Easy Learning, TutorialsPoint, http://www.tutorialspoint.com/unix_system_calls/wait.htm Linux man pages: http://linux.die.net/man/2/execve http://man7.org/linux/man-pages/man3/execl.3.html 鳥哥的私房菜 http://linux.vbird.org/linux_basic/0440processcontrol.php

本小節課程結束