OS Design and Implementation读书笔记(2)

这篇博客详细介绍了MINIX3操作系统中的系统调用,包括进程相关的fork(), waitpid(), execve(), sbrk();信号处理的sigaction(), sigreturn(), sigprocmask(), sigsuspend(), pause();以及文件操作的open(), read(), write(), lseek(), dup(), pipe(), ioctl(), access(), rename()和fcntl()。这些调用是操作系统中实现进程交互、文件管理和信号处理的基础。" 112476676,10530310,Python 变量与常量详解,"['Python教程', '基础语法', '动态语言', '数据类型', '常量']
摘要由CSDN通过智能技术生成

系统调用(在MINIX3中):

进程相关:
在这里插入图片描述
1,fork()。创建一个原进程的副本进程。原进程与新进程中的内容完全相同,但各自执行互不相关。fork函数有返回值,返回值为0时当前进程为子进程,返回值为一个正整数(为子进程的标识号PID)时当前进程为父进程。

2,waitpid()。该系统调用使父进程阻塞,直到子进程结束。waitpid函数有3个参数。
若第一个参数设置为-1,waitpid函数等待某个特定的子进程。
第二个参数statloc指向的是子进程的返回值

3,execve()。使得子进程必须执行当前的用户命令。
函数有三个参数:待执行文件名,指向参数数组的指针,指向环境数组的指针

举例:shell的运行( C语言 )

#define TRUE 1

while(TRUE){
	type_prompt();                /*在屏幕上显示提示符*/
	read_command(command, parameters); /*从终端读取输入*/

	if(fork != 0)                /*如果是子进程*/
		waitpid(-1, &status, 0); /*阻塞父进程*/
	else                       /*如果是父进程*/
		execve(command, parameters, 0); /*执行命令*/
}

4,sbrk()。改变进程的数据段的大小。函数唯一一个参数为数据段的增加字节数(负数时为减少字节数),类比malloc动态申请内存函数函数

进程分为三段,代码段和数据段从下到上增长,栈段从上到下增长,中间的区域为空闲区。


信号相关:

在这里插入图片描述

|| 例如用户:对正在运行的编辑器按下看CTRL + C,就是向进程发送了一个终止的信号 或者kill系统调用也是给进程的撤销信号,alarm系统调用定时给进程SIGALRM警告信号

1,sigaction()。对于尚未声明愿意接受信号的进程来说,若它接受到了一个信号,那么进程就会被杀死,因此我们会使用sigaction函数来声明进程将准备接收信号。
调用完sigaction函数以后,进程可接收信号,并进行相应的信号处理程序
该函数有2个参数,一个是信号处理程序的地址,一个是原先信号处理程序的地址

sigaction()配合SIG_IGN可以使得进程忽略某信号 eg:sigaction(SIGQUIT, SIG_IGN, NULL);

2,sigreturn()。信号处理结束后,调用sigreturn函数,将返回到原来被此次信号打断的指令继续向下执行。

3,sigprocmask()。信号也是可以被阻塞的,被阻塞的进程会一直挂起,即不传递也不丢失直到阻塞解除。我们使用sigprocmask允许进程定义一组被阻塞的信号集

4,sigsuspend()。允许进程将阻塞的信号挂起

5,sigsuspend()。进程使用该函数查询因阻塞而挂起的信号集

6,pause()。若一个进程需要一个信号才去启动,在它接收到信号以前可以让它进行空循环以等待信号,但为了不占用CPU,最好的办法就是将进程挂起等待信号到来


文件相关:
在这里插入图片描述1,open()。读写一个文件时首先我们需要打开文件,第一个参数为文件路径(绝对路径或相对路径),第二个参数为打开方式 (O_RDONLY, O_WRONLY, O_RDWR)
对应函数close(), 可以接触文件描述符fd与文件之间的联系

2,read() / write()。常见的文件操作!!原来是系统调用

3,lseek()。读写通常来说时顺序执行的,lseek系统调用可以直接修改文件指针的位置。
该函数有3个参数,第一个参数时文件描述符,第二个时文件的位置,第三个指明文件指针位置相对于文件开头,结尾还是当前位置

4,dup()。相当于给文件的文件描述符起别名的函数

5,pipe()。创建一个管道(虚拟文件),并返回两个文件描述符,一个用于写一个用于读
以下在进程中创建管道的实例:

#define STD_INPUT 0   /*标准输入的文件描述符*/
#define STD_OUTPUT 1 /*标准输出的文件描述符*/

pipeLine(process1, process2)
char *process1, *process2;  /*指向程序名的指针*/
{	
	int fd[2];
	pipe(&fd[0]);   /*创建一个管道*/
	if(fork != 0){
	   /*为父进程时*/
		close(fd[0]);   /*进程1只需要向管道写*/
		close(STD_OUTPUT);  /*准备新的标准输出*/
		dup(fd[1]);   /*将标准输出指向fd[1]*/
		close(fd[1]);  /*不再需要此文件描述符了*/
		execl(procress1, process1, 0);
	}
	else{
		/*为子进程时*/
		close(fd[1]);	/*进程2只需要从管道中读*/
		close(STD_INPUT);  /*准备新的标准输入*/
		dup(fd[0]);
		close(fd[0]);
		execl(process2, process2, 0);
	}
}

|| ioctl()。主要用途在于字符设备文件(特别是终端),可以改变终端模式与属性

终端(Terminal),是计算机网络中处于网络最外围的设备,主要用于用户信息的输入以及处理结果的输出等
终端 的三大模式:熟模式,生模式和 cbreak模式
熟模式 (正规模式):最常用的终端模式。在该模式下,字符的删除和终止能正常工作,CTRL+S / CTRL+Q 停止和恢复终端输出,CTRL+D表示文件的结束,CTRL+C组合键残生一个终端信号,CTRL+\ 产生一个退出信号并强势进行内核映像转储
生模式 (非正规模式):上述功能全部取消,每个字符都是在未加处理的情况下直接发送到程序(熟模式是输入了一整行后再发送)
cbreak  (非正规模式):上述功能部分取消,每个字符都是在未加处理的情况下直接发送到程序(介乎生熟之间)

|| access() 检查文件按范文操作是否具有相应的权限 // rename() 改变一个文件的名字,其参数为旧文件名和新文件名 fcntl() 最常用于文件加锁

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值