行程(process).

Slides:



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

C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
第1单元 操作系统概论 第一节 绪论 操作系统定义.
四資二甲 第三週作業 物件導向程式設計.
第一章 C语言概述 计算机公共教学部.
操作系统原理 Principles of Operating System
基于操作系统的编程复习 张玉宏
新世代計算機概論 第14章 程式語言.
Using C++ The Weird Way Something about c++11 & OOP tricks
第8章 字元與字串處理 8-1 C語言的字元檢查函數 8-2 C語言的字串 8-3 字串的輸入與輸出 8-4 指標與字串
南京天石软件技术有限公司 陈锺 (QQ: Solaris 10 C编程 南京天石软件技术有限公司 陈锺 (QQ:
高级语言程序设计 主讲人:陈玉华.
Compilers Flex & Bison 的安裝使用
函數 授課:ANT 日期:2009/3/24.
物件導向程式設計 (Object-Oriented rogramming)
chapter 1-Introduction
Shell Script 程式設計.
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
单片机原理与应用 C/C++在现代数字计算机上的实现.
C 程式設計— 指標.
函數 授課:ANT 日期:2011/3/28.
第7章 Linux环境编程.
助教:胡光能,解定宝 编译原理讲师:戴新宇
C 程式設計— 指標 台大資訊工程學系 資訊系統訓練班.
第四讲 MPI并行程序设计 课程网站:CourseGrading buaa.edu.cn 主讲教师: 赵长海
多进程编程.
STRUCTURE 授課:ANT 日期:2010/5/12.
计算概论 第十八讲 C语言高级编程 结构与习题课 北京大学信息学院.
Function.
程序设计期末复习 黎金宁
第三章 C++中的C 面向对象程序设计(C++).
程式撰寫流程.
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第3章 堆栈和队列 堆栈 堆栈应用 队列 队列应用 优先级队列 主要知识点.
字符串和字符数组 字符串的输入和输出 字符串的基本操作
第五章 C/C++及汇编语言的混合编程 5.1 ARM C/C++编译器 5.2 在C/C++程序中内嵌汇编指令
第十章 指针.
实验一、进程控制 一、实验目的 1、加深对进程的理解,进一步认识并发执行的实质; 2、分析进程争用资源现象,学习解决进程互斥的方法;
Struct結構 迴圈
第4讲 C++程序控制结构(二) 4.1 循环结构 4.2 转向控制 4.3 综合案例分析.
C++ 程式設計 基礎篇 張啟中 Chang Chi-Chung.
自我參考結構 (self-reference – 1)
辅导课程八.
7.1 广义表的概念 广义表是n(n≥0)个数据元素组成的序列,其中每个数据元素或是单个数据元素(简称原子),或仍然是一个广义表 。
鄧姚文 資料結構 第五章:遞迴 鄧姚文
資料結構與C++程式設計進階 排序與搜尋 講師:林業峻 CSIE, NTU 6/ 14, 2010.
函式庫補充資料.
Oop8 function函式.
第7章 進階的同步 觀念與實務.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
C標準輸出入函數庫 與 作業系統.
C程序设计.
第7章 程序的结构 四、生存期与存储属性 五、extern关键字与外部连接属性 六、static关键字与内部连接属性.
第二章 类型、对象、运算符和表达式.
累堆排序法 (Heap Sort).
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A Lab7.
C程序设计.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
挑戰C++程式語言 ──第9章 函數.
实验二:添加Linux系统调用及熟悉常见系统调用
2017 Operating Systems 作業系統實習 助教:陳主恩、林欣穎 實驗室:720A Lab4.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
作業一: 安裝Linux於btrfs上 中正大學 作業系統實驗室 指導教授:羅習五
辅导课程十二.
第6章 嵌入式软件开发基础.
2019 Operating Systems 作業系統實習 助教:林欣穎 實驗室:720A Lab7.
《操作系统设计与实现》 第5章 文件系统.
《操作系统设计与实现》 Linux系统编程.
隨機函數.
Presentation transcript:

行程(process)

什麼是行程

什麼是行程 作業系統先用一對一的「對應」將一個ELF(一種執行檔格式)映 射到記憶體中 再由作業系統依照實際的需求,擴增data session(透過brk或 mmpae等系統呼叫)及stack(自動長大) 動態連結庫(shared object, so)則由作業系統依照當時是否已經 把shared object(so)已經載入到記憶體,決定是否要載入該so或 只要將該so映射到這個行程的記憶體空間 so通常位於stack與heap之間

程式的參數 啟動行程時,可以帶上參數,這些參數如下一頁投影片所示

程式的參數 一個標準的GNU C的主程式應該下底下這樣 int main(int argc, char**argv) { int i=0; #include <unistd.h> #include <stdlib.h> while(argv[i]!=NULL) { #include <stdio.h> printf("%s\n", argv[i]); i++; /*argc,代表在呼叫這個執行檔的時候,總共 有幾個參數*/ } /*請注意,第一個參數一定是執行檔的檔名, 這樣的設計,有助於除錯*/ /*依照程式的屬性,設定適當的return value*/ /*例如在pipe中(後面張婕蕙教授),可以將 檔名當成輸出資料的一部份*/ return 1; /*argv則是字串陣列,最後一個字串是NULL*/

執行結果 $ ./echo para1 para2 para3 ./echo para1 para2 para3

程式的執行環境: 環境變數

在command模式的設定法 myname=shiwulo 注意,等號的二邊不可以加上空白字元 變數的開頭不可以是數字,變數名稱不可以是英數以外的東西,例如: @mail是不可以的 變數的內容如果有空白,可以用單引號「’」或雙引號「“」包起來 可以使用跳脫字元「\」將特殊的字元(空白、@等)加入變數 如果要附加(append)到一個變數,可以用下列形式: 例:PATH=“PATH”:myname=shiwulo 取消用unset,例如:unset myname 如果要將該變數傳給子行程,要加上export,例如:export myname

課堂作業 將你的英文名字export成環境變數 將「./」加到PATH內 試試看,如果執行目前目錄的執行檔,還需要加上「./myexe」或者 「myexe」就好 這可能會造成安全性的漏洞

user environment相關的函數及變數 #include <stdlib.h> char *getenv(const char *name); int putenv(char *string); extern char **environ;

listEnv #include <stdlib.h> #include <stdio.h> extern char **environ; int main(int argc, char**argv) { int i; while(environ[i] != NULL) { printf("%s\n", environ[i++]); }

執行結果 XDG_VTNR=7 XDG_SESSION_ID=c2 ... XDG_RUNTIME_DIR=/run/user/1000 DISPLAY=:0 XDG_CURRENT_DESKTOP=Unity GTK_IM_MODULE=ibus LESSCLOSE=/usr/bin/lesspipe %s %s TEXTDOMAINDIR=/usr/share/locale/ COLORTERM=gnome-terminal XAUTHORITY=/home/shiwulo/.Xauthority _=./listEnv

getenv #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int i; char* value; for (i=1; argv[i]!=NULL; i++) { value = getenv(argv[i]); printf("%s=%s\n", argv[i], value); } return 0;

執行結果 ./getEnv PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/g ames:/usr/local/games

程式碼的結束呼叫

程式的結束 程式結束時,作業系統會回收幾乎所有的資源,並且讓這個程式 進入殭屍模式(zombie,下一個章節會介紹)。 我們可以「註冊」一些函數,讓程式碼「正確的結束時」,將執 行這些函數。 例如:釋放shared memory 例如:釋放網路的socket

atexit #include <stdlib.h> int atexit(void (*function)(void)); int on_exit(void (*function)(int , void *), void *arg); atexit 在程式正常結束時,作業系統(OR compiler)會幫我們呼 叫函數:function on_exit在程式正常結束時,將呼叫所註冊的函數,該函數的第一 個參數是「該程式的回傳值」,第二個變數則是一個指標(使用 者可以自行應用) on_exit目前只能在Linux上使用

atexit #include <stdio.h> #include <stdlib.h> void myName() { printf("shiwulo\n"); } int main(int argc, char **argv) { atexit(myName); return 0;

執行結果 $ ./atexit shiwulo

控制行程的 優先權及多核心排程

改變行程的優先權 對大部分的系統而言(包含Linux)優先權越小,就能拿到更高的 優先權(或者是提升優先權) 例如:優先權0是系統中最高的優先權 例如:優先權139是系統最低的優先權 通常只有root可以提升優先權,其他使用者只能降低優先權 在Linux中,撰寫程式時不可以假設底層的優先權處理機制 例如:為了避免競賽問題(race condition),假設高優先權的工作做完 以後,才執行低優先權的工作。

變更優先權 Linux指令 函數呼叫 #include <unistd.h> nice 函數呼叫 #include <unistd.h> int nice(int inc); /*回傳值為先的優先權*/

myNice.c #include <stdio.h> #include <unistd.h> #include <errno.h> int main(int argc, char **argv) { int niceVal; int newNiceVal; sscanf(argv[1], "%d", &niceVal); errno =0; newNiceVal = nice(niceVal); if (newNiceVal == -1 && errno !=0) perror("nice"); else printf("new val = %d\n", newNiceVal); return 0; }

執行結果 ./myNice 10 new val = 10 shiwulo@ubuntu:~/Desktop/sp/ch9$ ./myNice -10 nice: Operation not permitted shiwulo@ubuntu:~/Desktop/sp/ch9$ sudo ./myNice -10 new val = -10

相關的巨集指令 #define _GNU_SOURCE #include <sched.h> void CPU_ZERO(cpu_set_t *set); void CPU_SET(int cpu, cpu_set_t *set); void CPU_CLR(int cpu, cpu_set_t *set); int CPU_ISSET(int cpu, cpu_set_t *set); int CPU_COUNT(cpu_set_t *set);

相關巨集的意義 CPU_ZERO() Clears set, so that it contains no CPUs. CPU_SET() Add CPU cpu to set. CPU_CLR() Remove CPU cpu from set. CPU_ISSET() Test to see if CPU cpu is a member of set. CPU_COUNT() Return the number of CPUs in set.

相關的函數 #define _GNU_SOURCE #include <sched.h> int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t cpusetsize,

cpu_set #define _GNU_SOURCE for(j=0; j<10000000; j++) { #include <sched.h> j=j+1; #include <errno.h> } #include <stdio.h> ret=sched_setaffinity(0, sizeof(cpu_set_t), &set); if (ret==-1) int main(int argc, char **argv) { perror("sched_setaffinity"); cpu_set_t set; CPU_ZERO(&set); return j; int i,j,ret; for(i=0; i<1000; i++) { CPU_SET(3, &set);

執行結果