產生新的程序:fork() (2/4) fork()回傳時,若成功 若fork()失敗,則回傳-1 新子程序將被加入於系統中

Slides:



Advertisements
Similar presentations
Linux 操作系统分析 中国科学技术大学计算机系 陈香兰( 0512 - ) Autumn 2010.
Advertisements

Linux 环境及 Shell 程序 操作系统实验 1. 二、 Shell 编程与进程通信 常用 shell 命令 文件及文件属性操作 ls 、 cp 、 mv 、 rm ln 、 ln –s 、 chmod 、 groupadd 、 useradd 输入输出操作 echo 、 cat >> 、
第1单元 操作系统概论 第一节 绪论 操作系统定义.
行程(process).
第七章 操作系统接口 7.1 联机用户接口 7.2 Shell命令语言 7.3 系统调用 7.4 UNIX系统调用 7.5 图形用户接口.
第一章 C语言概述 计算机公共教学部.
UNIX的程序與工作控制 程序的定義與特性 程序的建立 相關指令 背景執行 調整程序優先權 signal與kill 工作控制
操作系统原理 Principles of Operating System
第七章 异常控制流 CPU控制流的概念 进程上下文切换 异常和中断的基本概念 异常和中断的响应和处理
補充: Input from a text file
基于操作系统的编程复习 张玉宏
Operating System Concepts 作業系統原理 Chapter 3 行程觀念 (Process Concept)
MPI并行程序设计简介 曙光信息产业(北京)有限公司 2018年11月.
南京天石软件技术有限公司 陈锺 (QQ: Solaris 10 C编程 南京天石软件技术有限公司 陈锺 (QQ:
第一章 C语言概述.
Chapter 1 用VC++撰寫程式 Text book: Ivor Horton.
函數 授課:ANT 日期:2009/3/24.
chapter 1-Introduction
并行计算实验上机 国家高性能计算中心(合肥).
中国科学技术大学计算机系 陈香兰(0512- ) Spring 2011
簡易 Visual Studio 2010 C++ 使用手冊
作 業 系 統 第三組 楊育翰 顏瑞霖.
C 程式設計— 指標.
編譯環境介紹.
第7章 Linux环境编程.
第四讲 MPI并行程序设计 课程网站:CourseGrading buaa.edu.cn 主讲教师: 赵长海
第十一章 文件 文件概述 文件操作 文件操作实例 本章小结 作业: 练习:
Chapter 3 行程觀念 (Process Concept)
多进程编程.
STRUCTURE 授課:ANT 日期:2010/5/12.
Function.
程式撰寫流程.
实践演练 广州创龙电子科技有限公司 01 广州创龙电子科技有限公司
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
Introduction to Multimedia Coding
进程操作.
Process management(程序管理)
Linux操作系统分析 中国科学技术大学计算机系 陈香兰(0512- )
重點 資料結構之選定會影響演算法 選擇對的資料結構讓您上天堂 程式.
THE C PROGRAMMING LANGUAGE
$16 进程和线程. $16 进程和线程 进程 进程 属性 ProcessName / Id MachineName / MainModule BasePriority StartTime / ExitTime TotalProcessorTime / UserProcessorTime PrivateMemorySize64.
簡易 Visual Studio 2005 C++ 使用手冊
第3章 認識處理元.
实验一、进程控制 一、实验目的 1、加深对进程的理解,进一步认识并发执行的实质; 2、分析进程争用资源现象,学习解决进程互斥的方法;
第2章 进程和线程 内容提要: 2.1 进 程 概 念 2.2 进程的状态和组成 2.3 进 程 管 理 2.4 线 程.
序及第0章.
C++ 程式設計 基礎篇 張啟中 Chang Chi-Chung.
熊博安 教授.
Oop8 function函式.
C標準輸出入函數庫 與 作業系統.
輸出與輸入(I/O).
Pthread.
第三章 基本的輸出與輸入函數 (Basic Output & Input Function)
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A Lab7.
C程序设计.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序管理 蘇偉順助教.
挑戰C++程式語言 ──第9章 函數.
 隐式欧拉法 /* implicit Euler method */
程序管理 蘇偉順助教.
Computer Science & Information Management
实验二:添加Linux系统调用及熟悉常见系统调用
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A Lab4.
Arguments to the main Function and Final Project
作業一: 安裝Linux於btrfs上 中正大學 作業系統實驗室 指導教授:羅習五
第6章 嵌入式软件开发基础.
2019 Operating Systems 作業系統實習 助教:林欣穎 實驗室:720A Lab7.
函式庫補充資料 1.
《操作系统设计与实现》 Linux系统编程.
隨機函數.
Presentation transcript:

產生新的程序: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

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

Lab 1 列印所有可註冊的signal #include <stdlib.h> #include <signal.h> #include <stdio.h> void sighandler(int signumber) { printf("get a signal named '%d', '%s'\n", signumber, sys_siglist[signumber]); } int main(int argc, char **argv) { int sig_exist[100]; int idx = 0; for (idx = 0; idx < 100; idx++) { if (signal(idx, sighandler) == SIG_ERR) {

Lab 1 列印所有可註冊的signal sig_exist[idx] = 0; } else { sig_exist[idx] = 1; for (idx = 0; idx < 100; idx++) { if (sig_exist[idx] == 1) printf("%2d %s\n", idx, sys_siglist[idx]); printf("my pid is %d\n", getpid()); printf("press any key to resume\n"); getchar();

Lab 1: results (MAC OS X) 1 Hangup 2 Interrupt 3 Quit 4 Illegal instruction 5 Trace/BPT trap 6 Abort trap 7 EMT trap 8 Floating point exception 10 Bus error 11 Segmentation fault 12 Bad system call 13 Broken pipe 14 Alarm clock 15 Terminated 16 Urgent I/O condition 18 Suspended 19 Continued 20 Child exited 21 Stopped (tty input) 22 Stopped (tty output) 23 I/O possible 24 Cputime limit exceeded 25 Filesize limit exceeded 26 Virtual timer expired 27 Profiling timer expired 28 Window size changes 29 Information request 30 User defined signal 1 31 User defined signal 2

Lab 1: results (Linux) 1 Hangup 2 Interrupt 3 Quit 4 Illegal instruction 5 Trace/breakpoint trap 6 Aborted 7 Bus error 8 Floating point exception 10 User defined signal 1 11 Segmentation fault 12 User defined signal 2 13 Broken pipe 14 Alarm clock 15 Terminated 16 Stack fault 17 Child exited 18 Continued 20 Stopped 21 Stopped (tty input) 22 Stopped (tty output) 23 Urgent I/O condition 24 CPU time limit exceeded 25 File size limit exceeded 26 Virtual timer expired 27 Profiling timer expired 28 Window changed 29 I/O possible 30 Power failure 31 Bad system call

Lab 1: results (Linux) 試試看 kill -4 pid 調整terminal window的大小

Lab2: segmentation fault 試試看”故意存取錯誤的記 憶體”

示意圖 父行程 子行程 子行程 stdout stdin

aio.c int count=0; void aioSigHandler(int sig, siginfo_t *si, void *ucontext) { count++; } int main(int argc, char **argv) { int i, ret; int start, end; struct sigaction sa; int fd; struct aiocb aiocb_ary[1000]; char buf[1000][4096]; memset(buf, 'a', 1000*4096); fd=open("./tmp",O_RDWR); sa.sa_flags = SA_RESTART | SA_SIGINFO; sa.sa_sigaction = aioSigHandler; if (sigaction(SIGUSR1, &sa, NULL) == -1)

aio.c perror("sigaction"); start = clock(); for(i=0; i<1000; i++) { aiocb_ary[i].aio_buf = &buf[i][0]; aiocb_ary[i].aio_fildes = fd; //stdin aiocb_ary[i].aio_nbytes = 4096; aiocb_ary[i].aio_offset = 4096*i; aiocb_ary[i].aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocb_ary[i].aio_sigevent.sigev_signo = SIGUSR1; if (aio_write(&aiocb_ary[i]) != 0) perror("aio_read"); } end = clock(); printf("aio time = %d/%ld sec\n", end - start, CLOCKS_PER_SEC); printf("I/O # = %d\n", count); for (i=0; i<100000; i++) ; printf("finish! I/O # = %d\n", count); return 0;

Pthead PI Rand不是reentrant function,如果一定要使用,記得用mutex包起 來 平行度越高也要計算得越快

Shared memory PI Rand不是reentrant function,但在process中可用乎?確保每個 process的random seed不一樣 平行度越高也要計算得越快