操作系统实验-进程控制
操作系统实验报告进程管理
操作系统实验报告进程管理操作系统实验报告:进程管理引言操作系统是计算机系统中的核心软件,负责管理计算机的硬件资源和提供用户与计算机之间的接口。
进程管理是操作系统的重要功能之一,它负责对计算机中运行的各个进程进行管理和调度,以保证系统的高效运行。
本实验报告将介绍进程管理的基本概念、原理和实验结果。
一、进程管理的基本概念1. 进程与线程进程是计算机中正在运行的程序的实例,它拥有独立的内存空间和执行环境。
线程是进程中的一个执行单元,多个线程可以共享同一个进程的资源。
进程和线程是操作系统中最基本的执行单位。
2. 进程状态进程在运行过程中会经历不同的状态,常见的进程状态包括就绪、运行和阻塞。
就绪状态表示进程已经准备好执行,但还没有得到处理器的分配;运行状态表示进程正在执行;阻塞状态表示进程由于某些原因无法继续执行,需要等待某些事件的发生。
3. 进程调度进程调度是操作系统中的一个重要任务,它决定了哪个进程应该获得处理器的使用权。
常见的调度算法包括先来先服务(FCFS)、最短作业优先(SJF)和时间片轮转等。
二、进程管理的原理1. 进程控制块(PCB)PCB是操作系统中用于管理进程的数据结构,它包含了进程的各种属性和状态信息,如进程标识符、程序计数器、寄存器值等。
通过PCB,操作系统可以对进程进行管理和控制。
2. 进程创建与撤销进程的创建是指操作系统根据用户的请求创建一个新的进程。
进程的撤销是指操作系统根据某种条件或用户的请求终止一个正在运行的进程。
进程的创建和撤销是操作系统中的基本操作之一。
3. 进程同步与通信多个进程之间可能需要进行同步和通信,以实现数据共享和协作。
常见的进程同步与通信机制包括互斥锁、信号量和管道等。
三、实验结果与分析在本次实验中,我们使用了一个简单的进程管理模拟程序,模拟了进程的创建、撤销和调度过程。
通过该程序,我们可以观察到不同调度算法对系统性能的影响。
实验结果显示,先来先服务(FCFS)调度算法在一些情况下可能导致长作业等待时间过长,影响系统的响应速度。
进程控制实验报告
一、实验目的本次实验旨在通过Linux操作系统的实践操作,加深对进程控制概念的理解。
通过学习进程的创建、调度、同步、通信等基本操作,掌握进程控制的基本方法,并了解进程间通信的机制。
二、实验环境1. 硬件环境:Intel(R) Core(TM) i5-3210M CPU2.50GHz,4.00GB内存。
2. 软件环境:64位Linux操作系统。
三、实验内容1. 进程的创建与终止2. 进程的调度与优先级3. 进程同步与互斥4. 进程间通信四、实验步骤1. 进程的创建与终止(1)使用`fork()`函数创建子进程,通过比较返回值判断创建是否成功。
```cpid_t pid = fork();if (pid < 0) {perror("fork failed");exit(1);}```(2)使用`exit()`函数终止进程。
```cexit(0);```2. 进程的调度与优先级(1)使用`nice()`函数调整进程优先级。
```cnice(10); // 降低进程优先级```(2)使用`priority_seta()`函数设置进程优先级。
```cstruct sched_param param;param.sched_priority = 10;if (sched_setscheduler(pid, SCHED_RR, ¶m) == -1) { perror("sched_setscheduler failed");exit(1);}```3. 进程同步与互斥(1)使用`semaphore_t`类型的信号量实现进程同步。
```csemaphore_t sem;sem_init(&sem, 0, 1);sem_wait(&sem);// 执行临界区代码sem_post(&sem);sem_destroy(&sem);```(2)使用`mutex_t`类型的互斥锁实现进程互斥。
操作系统进程控制实验报告
操作系统进程控制实验报告硬件环境:处理器:Intel(R) Core(TM) i5-3210M CPU @2.50GHz 2.50GHz安装内存:4.00GB系统类型:64位操作系统软件环境:Linux系统一、实验目的加深对于进程并发执行概念的理解。
实践并发进程的创建和控制方法。
观察和体验进程的动态特性。
进一步理解进程生命期期间创建、变换、撤销状态变换的过程。
掌握进程控制的方法,了解父子进程间的控制和协作关系。
练习Linux系统中进程创建与控制有关的系统调用的编程和调试技术。
二、实验步骤(1)分析实例实验(2)进行独立实验(3)思考并完成实验报告实验截图:思考:说明它们反映出操作系统教材中进程及处理机管理一节讲解的进程的哪些特征和功能?在真实的操作系统中它是怎样实现和反映出教材中讲解的进程的生命期、进程的实体和进程状态控制的。
你对于进程概念和并发概念有哪些新的理解和认识?子进程是如何创建和执行新程序的?信号的机理是什么?怎样利用信号实现进程控制?根据实验程序、调试过程和结果分析写出实验报告。
1.进程的概念:进程不仅是一段程序代码,还包括当前活动(通过程序计数器和寄存器中的内容来表示),另外,进程还包括进程堆栈段,和数据段等。
2.并发概念:是指进程之间交替并发执行3.进程通过系统调用fork()函数创建子进程,子进程由唯一的pid值标示,pid通常是一个整数值。
通过fork创建的子进程实际上是父进程的克隆体,通过复制原来进程的地址空间而成,父子进程同时执行fork之后的程序。
但是父子进程的pid值不同,可以通过对pid的判断,使父子进程执行不同的程序。
子进程如果想执行不同的程序,需要系统调用exec()函数装入新的程序执行。
4.信号的机理:信号是用来通知进程某个特定的事件已经发生。
信号是由特定的事件产生,信号必须要发送到进程,一旦发送,进程必须得到处理。
信号可以可以有系统默认处理也可以用户自定义处理。
操作系统实验3-进程控制
WORD wMajorReq=(WORD)(dwVerReq>16);
WORD wMinorReq=(WORD)(dwVerReq&0xffff);
::cout<<"Process ID:"<<dwIdThis<<",requires OS:"<<wMajorReq<<wMinorReq<<::endl;
{
//改变优先级
::SetPriorityClass(
::GetCurrentProcess(), //利用这一进程
HIGH_PRIORITY_CLASS); //改变为high
//报告给用户
::cout<<"Task Manager should indicate this "
"process is high priority."<<::endl;
//设置版本信息的数据结构,以便保存操作系统的版本信息
OSVERSIONINFOEX osvix;
::ZeroMemory(&osvix,sizeof(osvix));
osvix.dwOSVersionInfoSize=sizeof(osvix);
//提取版本信息和报告
::GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(&osvix));
Parent();
}
return 0;
}
分析:程序4-3.cpp说明了一个进程从“生”到“死”的整个一生,第一次执行时,它创建一个子进程,其行为如同“父亲”。在创建子进程之前,先创建一个互斥的内核对象,其行为对于子进程来说,如同一个“自杀弹”。当创建子进程时,就打开了互斥体并在其他线程中进行别的处理工作,同时等待着父进程使用ReleaseMutex()API发出“死亡”信号。然后用Sleep()API调用来模拟父进程处理其他工作,等完成时,指令子进程终止。
进程控制实验报告
测试过程: (实验中出现的问题、错误、解决方法)创建好项目和文件, 对文件进行编译和运行, 编译没有错误, 但是运行总是提示有2个错误。
解决办法:在新建项目的时候“新建”, 然后新建文件, 程序就可以正常的运行了。
实验总结:1、课下没有对Microsoft Visual c++ 6.0进行深入的研究, 还是好多问题不知道怎么解决, 好好钻研一下这个很有必要的啊!评语与成绩:教师签名:年月日实验名称进程控制实验类型验证性实验时间实验环境Windows xp 、Microsoft Visual c++ 6.0实验目的与要求:1.通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作, 进一步熟悉操作系统的进程概念, 理解Windows 2000进程的“一生”。
2.通过阅读和分析实验程序,学习创建进程、观察进程和终止进程的程序设计方法。
实验内容:本实验给出了三段程序:创建进程、正在运行的进程和终止进程, 阅读程序回答所提问题, 分析运行结果。
一、实验步骤: (算法描述、源程序、操作步骤和方法)二、创建进程回答问题:1.该程序是一个简单使用CreateProcess()API函数的例子。
首先形成简单的命令行, 提供当前EXE文件的指定文件名和代表生成克隆进程的号码。
大多数参数都可取默认值, 但是创建标志参数使用了CREATE_NEW_CONSOLE标志, 指示新进程分配自己的控制台, 这使得运行程序时, 在任务栏上产生许多活动标记。
然后该克隆进程的创建方法关闭传递过来的句柄并返回main ()函数。
在关闭程序之前, 每一进程的执行主线程暂停一下, 以便让用户看到其中的至少一个窗口。
2、CreateProcess()函数有几个核心参数?本实验程序中设置的各个参数的值是什么?答、CreateProcess()函数有10个核心参数参数的值为: CreateProcess(szFilename, //产生这个EXE的应用程序的名称szCmdLine, //告诉其行为像一个子进程的标志NULL, //缺省的进程安全性NULL, //缺省的线程安全性FALSE, //不继承句柄CREATE_NEW_CONSOLE, //使用新的控制台NULL, //新的环境NULL, //当前目录&si, //启动信息&pi);3.程序运行时屏幕显示的信息是什么?答、三、运行进程1、回答问题:2、给出运行结果(当前PID信息、操作系统版本、系统提示信息)答、运行结果为:2.如何获得当前的PID和操作系统版本可利用GetCurrentProcessId()API函数查看系统当前进程的标识符(pid), 该pid在整个系统中都可使用。
电大操作系统实验报告3_ 进程管理实验
电大操作系统实验报告3_ 进程管理实验电大操作系统实验报告 3 进程管理实验一、实验目的进程管理是操作系统的核心功能之一,本次实验的目的是通过实际操作和观察,深入理解进程的概念、状态转换、进程调度以及进程间的通信机制,掌握操作系统中进程管理的基本原理和方法,提高对操作系统的整体认识和实践能力。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C 语言,开发工具为 Visual Studio 2019。
三、实验内容及步骤(一)进程的创建与终止1、编写一个 C 程序,使用系统调用创建一个子进程。
2、在父进程和子进程中分别输出各自的进程 ID 和父进程 ID。
3、子进程执行一段简单的计算任务,父进程等待子进程结束后输出结束信息。
以下是实现上述功能的 C 程序代码:```cinclude <stdioh>include <stdlibh>include <unistdh>int main(){pid_t pid;pid = fork();if (pid < 0) {printf("创建子进程失败\n");return 1;} else if (pid == 0) {printf("子进程:我的进程 ID 是%d,父进程 ID 是%d\n",getpid(), getppid());int result = 2 + 3;printf("子进程计算结果:2 + 3 =%d\n", result);exit(0);} else {printf("父进程:我的进程 ID 是%d,子进程 ID 是%d\n",getpid(), pid);wait(NULL);printf("子进程已结束\n");}return 0;}```编译并运行上述程序,可以观察到父进程和子进程的输出信息,验证了进程的创建和终止过程。
(二)进程的状态转换1、编写一个 C 程序,创建一个子进程,子进程进入睡眠状态一段时间,然后被唤醒并输出状态转换信息。
操作系统实验3进程的创建控制实验
操作系统实验3进程的创建控制实验实验三的目标是通过实现一个进程控制程序,来加深我们对进程创建和控制机制的理解,并通过实践来熟悉和掌握相关的编程技巧。
在进行实验之前,我们需要先了解进程的一些基本概念和相关知识。
首先,进程的创建是通过操作系统中的系统调用来完成的。
在Linux系统中,常用的创建进程的系统调用有fork(和exec(。
fork(系统调用可以创建一个新的进程,该进程与调用fork(的进程几乎完全相同;而exec(系统调用则在新创建的进程中执行一个新的程序。
另外,进程的控制机制主要是通过进程的状态来实现的。
进程可以处于就绪状态、运行状态和阻塞状态。
就绪状态的进程可以被调度器选择后立即运行,而阻塞状态的进程则需要等待一些条件满足后才能被唤醒并变为就绪状态。
实验三的具体内容包括:1. 编写一个程序,通过调用fork(创建多个子进程。
子进程和父进程可以并行执行,共享程序的代码和数据段。
2. 子进程通过调用exec(系统调用执行不同的程序。
可以通过调用不同的exec(函数或者传入不同的参数来执行不同的程序。
3. 子进程执行的程序可能会产生不同的结果,比如输出不同的字符串或者产生不同的返回值。
我们可以通过wait(系统调用等待子进程退出,并获取子进程的返回值。
4. 父进程可以通过调用waitpid(系统调用来选择等待一些特定的子进程,以及获取特定子进程的返回值。
通过实验三的实践,我将更加深入地了解进程的创建和控制机制。
实验三的实验结果将让我熟悉和掌握相关的编程技巧,为我今后更加熟练地编写和控制进程打下坚实的基础。
总之,实验三是一个非常有意义的实验,将帮助我更加深入地理解进程的创建和控制机制,并通过实践获得相关的编程技巧。
这将对我今后的学习和实践有很大的帮助。
进程控制与进程通信程序实验报告
进程控制与进程通信程序实验报告一、引言进程是计算机系统中最基本的概念之一,是操作系统中最小的资源管理单位。
进程控制与进程通信是操作系统中重要的内容,涉及到进程的创建、调度和终止,以及进程间的信息传递和同步管理。
本实验旨在通过编写进程控制与进程通信程序,加深对操作系统中进程管理和通信机制的理解。
二、实验目的1. 理解进程的概念和特点,掌握进程的创建、调度和终止方法。
2. 掌握进程通信的基本原理和方法,包括共享内存、管道、消息队列和信号量等。
3. 能够编写简单的进程控制和进程通信程序。
三、实验内容1. 进程控制实验:编写一个程序,实现进程的创建、调度和终止。
通过调用系统调用函数,创建多个子进程,并通过进程控制函数实现父子进程的协作与同步。
2. 进程通信实验:编写一个程序,实现进程间的信息传递和同步管理。
通过共享内存、管道、消息队列或信号量等机制,实现不同进程之间的数据交换和共享。
四、实验步骤1. 进程控制实验:(1)创建父进程和子进程:使用fork()函数创建子进程,并通过判断返回值来区分父子进程。
(2)调度子进程:使用wait()函数等待子进程的结束,以实现父子进程的同步。
(3)终止子进程:使用exit()函数终止子进程的运行。
2. 进程通信实验:(1)共享内存:使用shmget()函数创建共享内存段,使用shmat()函数映射共享内存到进程的地址空间,实现共享数据的读写。
(2)管道:使用pipe()函数创建管道,使用fork()函数创建子进程,通过读写管道实现进程间的数据传输。
(3)消息队列:使用msgget()函数创建消息队列,使用msgsnd()函数向消息队列发送消息,使用msgrcv()函数从消息队列接收消息,实现进程间的消息传递。
(4)信号量:使用semget()函数创建信号量,使用semop()函数对信号量进行P操作和V操作,实现进程间的同步和互斥。
五、实验结果通过实验,我们成功实现了进程的创建、调度和终止,以及进程间的信息传递和同步管理。
实验一进程控制与描述
死锁检测
死锁检测是通过检测系统状态是否满足死锁条件来确定系 统是否处于死锁状态。
死锁解除
死锁解除是当系统检测到死锁状态时采取措施来解除死锁 的过程。
资源有序分配法
资源有序分配法是一种预防死锁的方法,通过为每个资源 分配一个唯一的序号,并要求进程按照序号递增的顺序请 求资源来避免产生循环等待条件。
03 进程描述
实验一:进程控制与描述
目录
• 进程控制概述 • 进程控制机制 • 进程描述 • 实验步骤与操作 • 实验结果与分析
01 进程控制概述
进程的定义与特性
总结词
进程是程序的一次执行,具有动态性、 并发性、制约性、独立性和制约性等特 性。
VS
详细描述
进程是程序在计算机上的一次执行过程, 它具有动态性,即进程的状态可以在运行 过程中改变;并发性,即进程可以同时存 在于多个状态;制约性,即进程间的相互 制约关系;独立性,即进程是独立的,不 受其他进程的影响;制约性,即进程间的 相互制约关系。
04 实验步骤与操作
实验环境搭建
准备实验所需的操作 系统环境,如Linux 或Windows。
配置网络连接,确保 实验过程中能够访问 外部资源。
安装必要的软件工具, 如任务管理器、终端 等。
进程创建与终止实验
01 打开任务管理器或终端,
查看当前运行的进程。
观察并记录进程的创建 过程和结果,包括进程
PCB中包含了进程标识符、进 程状态、内存指针、文件描述 符表等信息。
通过PCB,操作系统可以对进 程进行创建、切换、终止等操 作,实现对进程的统一管理。
进程状态信息
1
进程状态信息是指描述进程当前状态的变量和数 据结构。
实验1 进程控制与描述
实验一:进程控制与描述一、实验目的:利用Windows提供的API函数,编写程序,实现进程的创建和终止(如创建写字板进程及终止该进程),加深对操作系统进程概念的理解,观察操作系统进程运行的动态性能,获得包含多进程的应用程序编程经验。
二、实验原理:1.进程的创建进程的创建通过CreateProcess()函数来实现,CreateProcess()通过创建一个新的进程及在其地址空间内运行的主线程来启动并运行一个新的程序。
具体地,在执行CreateProcess()函数时,首先由操作系统负责创建一个进程内核对象,初始化计数为1,并立即为新进程创建一块虚拟地址空间。
随后将可执行文件或其他任何必要的动态链接库文件的代码和数据装载到该地址空间中。
在创建主线程时,也是首先由系统负责创建一个线程内核对象,并初始化为1。
最后启动主线程并执行进程的入口函数WinMain(),完成对进程和执行线程的创建。
2.实现技巧CreateProcess()函数的原型声明如下:BOOL CreateProcess(LPCTSTR lpApplicationName, // 可执行模块名LPTSTR lpCommandLine, // 命令行字符串LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程的安全属性LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程的安全属性BOOL bInheritHandles, // 句柄继承标志DWORD dwCreationFlags, // 创建标志LPVOID lpEnvironment, // 指向新的环境块的指针LPCTSTR lpCurrentDirectory, // 指向当前目录名的指针LPSTARTUPINFO lpStartupInfo, // 指向启动信息结构的指针LPPROCESS_INFORMATION lpProcessInformation //指向进程信息结构的指针)可以指定第一个参数,即应用程序的名称,其中包括相对于当前进程的当前目录的全路径或者利用搜索方法找到的路径;lpCommandLine参数允许调用者向新应用程序发送数据;接下来的三个参数与进程和它的主线程以及返回的指向该对象的句柄的安全性有关。
电大操作系统实验2:进程管理实验
电大操作系统实验2:进程管理实验
实验目的:
1.加深对进程概念的理解,特别是进程的动态性和并发性。
2.了解进程的创建和终止。
3.学会查看进程的状态信息。
4.学会使用进程管理命令。
实验要求:
1.理解有关进程的概念,能够使用ps命令列出系统中进
程的有关信息并进行分析。
2.理解进程的创建和族系关系。
3.能够使用&,jobs,bg,at等命令控制进程的运行。
实验内容:
1.使用ps命令查看系统中运行进程的信息。
实验环境:
实验步骤和结果:
1.输入ps命令,可以报告系统当前的进程状态。
2.输入ps-e命令,可以显示系统中运行的所有进程,包括系统进程和用户进程。
3.输入ps-f命令,可以得到进程的详细信息。
进程控制:
1.后台进程
1) $grep "注册用户名" /etc/passwd。
/tmp/abc &
2.作业控制
1) 进程休眠60秒Sleep 60 &
2) 进程休眠30秒Sleep 30 &
3) 查看进程状态Jobs
4) 将睡眠30秒的sleep命令放在前台执行fg%2
3.发送中断信号
1) 后台运行sleep命令$sleep 120 &
2) 查看sleep进程的状态$ps-p pid
3) 终止sleep命令$kill -9 pid。
实验一:进程控制描述与控制
实验一:进程控制描述与控制[1] Windows“任务管理器”的进程管理一、实验名称Windows“任务管理器”的进程管理二、实验目的通过在Windows 任务管理器中对程序进程进行响应的管理操作,熟悉操作系统进程管理的概念,学习观察操作系统运行的动态性能。
三、实验内容与步骤1. 使用任务管理器终止进程2. 显示其他进程计数器3. 更改正在运行的程序的优先级启动并进入Windows环境,单击Ctrl + Alt + Del键,或者右键单击任务栏,在快捷菜单中单击“任务管理器”命令,打开“任务管理器”窗口。
在本次实验中,你使用的操作系统版本是:_______Windows_XP______________________当前机器中由你打开,正在运行的应用程序有:1) _______ ________2) ___________实验一___3) _________操作系统_____________4) ___________百度首页________5) ____________ftp://172.16.20.168_______Windows“任务管理器”的窗口由____4__个选项卡组成,分别是:1) _______应用程序______________2) _进程__________________3) ______ 性能___________________4) ________联网__________________当前“进程”选项卡显示的栏目分别是(可移动窗口下方的游标/箭头,或使窗口最大化进行观察) :1. 使用任务管理器终止进程步骤1:单击“进程”选项卡,一共显示了__40___个进程。
请试着区分一下,其中:系统(SYSTEM) 进程有____25__个,填入表3-1中。
表3-1 实验记录服务(SERVICE) 进程有_____5_个,填入表3-2中。
表3-2 实验记录用户进程有___10___个,填入表3-3中。
操作系统进程管理实验报告
操作系统进程管理实验报告一、引言在现代计算机科学中,操作系统的进程管理是确保系统高效运行的关键环节。
本实验旨在通过观察和分析操作系统的进程管理行为,深入理解进程的创建、运行和终止过程,以及操作系统如何对进程进行调度和资源分配。
二、实验目标1、理解进程的基本概念、进程状态及转换。
2、掌握进程的创建、终止和调度方法。
3、观察和分析进程在运行过程中的资源消耗和调度行为。
4、分析操作系统对进程的资源分配和调度策略对系统性能的影响。
三、实验环境与工具本实验在Linux操作系统上进行,使用GNU/Linux环境下的工具进行进程的创建、监控和调度。
四、实验步骤与记录1、创建进程:使用shell命令“fork”创建一个新的进程。
记录下父进程和子进程的PID,以及它们在内存中的状态。
2、进程状态观察:使用“ps”命令查看当前运行进程的状态,包括进程的PID、运行时间、CPU使用率等。
同时,使用“top”命令实时监控系统的CPU、内存等资源的使用情况。
3、进程调度:在“crontab”中设置定时任务,观察系统如何根据预设的调度策略分配CPU资源给各个进程。
4、资源分配:通过修改进程的优先级(使用“nice”命令),观察系统如何调整资源分配策略。
5、终止进程:使用“kill”命令终止一个进程,并观察系统如何处理该进程占用的资源。
五、实验结果与分析1、创建进程:通过“fork”系统调用,成功创建了一个新的进程,并获取了父进程和子进程的PID。
在内存中,父进程和子进程的状态分别为“running”和“ready”。
2、进程状态观察:使用“ps”命令可以看到父进程和子进程的状态均为“running”,同时显示了它们的CPU使用率和运行时间等信息。
通过“top”命令,可以实时监控系统的CPU、内存等资源的使用情况,为进一步分析提供了数据支持。
3、进程调度:在“crontab”中设置定时任务后,系统会根据预设的调度策略以及各个进程的运行状态,动态地分配CPU资源给各个进程。
操作系统原理实验4-进程控制
《操作系统原理》实验报告
实验序号:4 实验项目名称:进程控制
一、实验目的及要求
1. 加深对进程信号量的理解。
2. 理解进程同步与互斥机制。
3. 掌握Linux操作系统下的进程控制编程。
二、实验设备(环境)及要求
1.虚拟机VMware Workstation、Ubuntu操作系统和C语言编程。
2.编写一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按Ctrl C键),当捕捉到中断信号后,父进程调用kill()向两个子进程发出信号,子进程捕捉到信号后,分别输出下面信息后终止:
child process 1 is killed by parent!
child process 2 is killed by parent!
父进程等待两个子进程终止后,输出以下信息后终止:
parent process is killed!
三、实验内容与步骤
代码:
在终端上进行测试
四、实验结果与数据处理
五、分析与讨论
了解了计算机进程的管理以及signal()函数的作用。
六、教师评语成绩。
操作系统实验之进程管理实验报告
操作系统实验之进程管理实验报告一、实验目的本次操作系统实验的主要目的是深入理解进程管理的概念和原理,通过实际操作和观察,掌握进程的创建、调度、同步与互斥等关键机制。
二、实验环境本次实验使用的操作系统为 Windows 10,开发工具为 Visual Studio 2019,编程语言为 C++。
三、实验内容1、进程创建使用系统提供的 API 函数创建新的进程。
观察新进程的资源使用情况和运行状态。
2、进程调度编写程序模拟不同的进程调度算法,如先来先服务(FCFS)、短作业优先(SJF)和时间片轮转(RR)。
比较不同调度算法下的平均周转时间、平均等待时间等性能指标。
3、进程同步与互斥利用信号量、互斥锁等机制实现进程之间的同步与互斥。
设计并发程序,解决生产者消费者问题、读写者问题等经典同步问题。
四、实验步骤1、进程创建实验首先,包含所需的头文件,如`<windowsh>`。
然后,定义创建进程的函数,使用`CreateProcess` 函数创建新进程,并获取进程的相关信息,如进程标识符、线程标识符等。
最后,通过查看任务管理器或其他系统工具,观察新创建进程的资源占用情况。
2、进程调度实验设计不同的调度算法函数,如`FCFSSchedule`、`SJFSchedule` 和`RRSchedule`。
在每个调度算法函数中,模拟进程的到达时间、服务时间等参数,并按照相应的算法进行进程调度。
计算每个进程的周转时间和等待时间,并求出平均周转时间和平均等待时间。
3、进程同步与互斥实验定义信号量或互斥锁变量。
在生产者消费者问题中,生产者在生产产品时获取互斥锁,生产完成后释放互斥锁并通知消费者;消费者在消费产品时获取互斥锁,消费完成后释放互斥锁。
在读写者问题中,读者在读取数据时获取共享锁,读完后释放共享锁;写者在写入数据时获取独占锁,写入完成后释放独占锁。
五、实验结果与分析1、进程创建实验结果成功创建新的进程,并能够获取到进程的相关信息。
操作系统实验---进程的创建与控制
实验报告实验题目姓名:学号:课程名称:操作系统实验所在学院:信息科学与工程学院专业班级:计算机任课教师:核心为fork( )完成以下操作:(1)为新进程分配一进程表项和进程标识符进入fork( )后,核心检查系统是否有足够的资源来建立一个新进程。
若资源不足,则fork( )系统调用失败;否则,核心为新进程分配一进程表项和唯一的进程标识符。
(2)检查同时运行的进程数目超过预先规定的最大数目时,fork( )系统调用失败。
(3)拷贝进程表项中的数据将父进程的当前目录和所有已打开的数据拷贝到子进程表项中,并置进程的状态为“创建”状态。
(4)子进程继承父进程的所有文件对父进程当前目录和所有已打开的文件表项中的引用计数加1。
(5)为子进程创建进程上、下文进程创建结束,设子进程状态为“内存中就绪”并返回子进程的标识符。
(6)子进程执行虽然父进程与子进程程序完全相同,但每个进程都有自己的程序计数器PC(注意子进程的注意子进程的PC 开始位置),然后根据pid 变量保存的fork( )返回值的不同,执行了不同的分支语句。
四、实验过程、步骤及内容1、编写一段程序,使用系统调用fork( )创建两个子进程。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:父进程显示'a',子进程分别显示字符'b'和字符'c'。
试观察记录屏幕上的显示结果,并分析原因。
2、修改上述程序,每一个进程循环显示一句话。
子进程显示'daughter …'及'son ……',父进程显示'parent ……',观察结果,分析原因。
3、用fork( )创建一个进程,再调用exec( )用新的程序替换该子进程的内容4、用fork( )建立如下形式的进程树:A进程B进程C进程D进程各个进程中都打印出本身PID 和其父进程的PID,并用wait( )来控制进程执行顺序,打印出正确和期望的结果。
操作系统实验报告 实验一 进程管理
实验一进程管理一、目的进程调度是处理机管理的核心内容..本实验要求编写和调试一个简单的进程调度程序..通过本实验加深理解有关进程控制块、进程队列的概念;并体会和了解进程调度算法的具体实施办法..二、实验内容及要求1、设计进程控制块PCB的结构PCB结构通常包括以下信息:进程名进程ID、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等..可根据实验的不同;PCB结构的内容可以作适当的增删..为了便于处理;程序中的某进程运行时间以时间片为单位计算..各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定..2、系统资源r1…r w;共有w类;每类数目为r1…r w..随机产生n进程P i id;s j;k;t;0<=i<=n;0<=j<=m;0<=k<=dt为总运行时间;在运行过程中;会随机申请新的资源..3、每个进程可有三个状态即就绪状态W、运行状态R、等待或阻塞状态B;并假设初始状态为就绪状态..建立进程就绪队列..4、编制进程调度算法:时间片轮转调度算法本程序用该算法对n个进程进行调度;进程每执行一次;CPU时间片数加1;进程还需要的时间片数减1..在调度算法中;采用固定时间片即:每执行一次进程;该进程的执行时间片数为已执行了1个单位;这时;CPU时间片数加1;进程还需要的时间片数减1;并排列到就绪队列的尾上..三、实验环境操作系统环境:Windows系统..编程语言:C..四、实验思路和设计1、程序流程图2、主要程序代码//PCB结构体struct pcb{public int id; //进程IDpublic int ra; //所需资源A的数量public int rb; //所需资源B的数量public int rc; //所需资源C的数量public int ntime; //所需的时间片个数public int rtime; //已经运行的时间片个数public char state; //进程状态;W等待、R运行、B阻塞//public int next;}ArrayList hready = new ArrayList;ArrayList hblock = new ArrayList;Random random = new Random;//ArrayList p = new ArrayList;int m; n; r; a;a1; b;b1; c;c1; h = 0; i = 1; time1Inteval;//m为要模拟的进程个数;n为初始化进程个数//r为可随机产生的进程数r=m-n//a;b;c分别为A;B;C三类资源的总量//i为进城计数;i=1…n//h为运行的时间片次数;time1Inteval为时间片大小毫秒//对进程进行初始化;建立就绪数组、阻塞数组..public void input//对进程进行初始化;建立就绪队列、阻塞队列{m = int.ParsetextBox4.Text;n = int.ParsetextBox5.Text;a = int.ParsetextBox6.Text;b = int.ParsetextBox7.Text;c = int.ParsetextBox8.Text;a1 = a;b1 = b;c1 = c;r = m - n;time1Inteval = int.ParsetextBox9.Text;timer1.Interval = time1Inteval;for i = 1; i <= n; i++{pcb jincheng = new pcb;jincheng.id = i;jincheng.ra = random.Nexta + 1;jincheng.rb = random.Nextb + 1;jincheng.rc = random.Nextc + 1;jincheng.ntime = random.Next1; 5;listBox1.Items.Add"产生进程ID:" + jincheng.id;listBox1.Items.Add"所需A资源数目:" + jincheng.ra;listBox1.Items.Add"所需B资源数目:" + jincheng.rb;listBox1.Items.Add"所需C资源数目:" + jincheng.rc;listBox1.Items.Add"所需时间片数:" + jincheng.ntime;if a - jincheng.ra >= 0 && b - jincheng.rb >= 0 && c - jincheng.rc >= 0{a = a - jincheng.ra;b = b - jincheng.rb;c = c - jincheng.rc;jincheng.state = 'W';hready.Addjincheng;//加入就绪队列}else{jincheng.state = 'B';hblock.Addjincheng;//加入阻塞队列}listBox1.Items.Add"当前进程状态:" + jincheng.state;}}//从数组起始地址开始输出该数组的内容public void dispArrayList list{ArrayList list1 = new ArrayList;list1 = list;if list1.Count > 0{for int j = 0; j < list1.Count; j++{pcb p = pcblist1j;listBox1.Items.Add" " + p.id.ToString + " " + p.state.ToString + " " + p.ra.ToString + " " + p.rb.ToString + " " + p.rc.ToString+" " + p.ntime.ToString + " " + p.rtime.ToString + " \r\n";}}else{listBox1.Items.Add"\r\n\t 该队列中没有进程\r\n";}}//输出就绪数组和阻塞数组的信息public void outputall{listBox1.Items.Add"当前就绪队列的信息";listBox1.Items.Add"进程ID 进程状态A资源数B资源数C资源数所需时间片已运行时间片";disphready;listBox1.Items.Add"当前就阻塞列的信息";listBox1.Items.Add"进程ID 进程状态A资源数B资源数C资源所需时间片已运行时间片";disphblock;}//运行就绪数组的头进程;运行一个时间片;轮转一个时间片;时间片轮转调度算法public void running{ArrayList hready1 = new ArrayList;hready1 = hready;pcb p1 = new pcb;p1=pcbhready10;p1.state='R';p1.rtime= p1.rtime + 1;h=h+1;listBox1.Items.Add"\r\n~~~~~~~当前正在运行进程ID是:" +p1.id + "~~~~~~~~\r\n";listBox1.Items.Add"\r\n进程ID 进程状态A资源数B资源数C资源数所需时间片已运行时间片\r\n";listBox1.Items.Addp1.id + " " +p1.state+ " " + p1.ra + " " + p1.rb + " " + p1.rc + " " + p1.ntime + " " + p1.rtime;if p1.ntime==p1.rtime{listBox1.Items.Addp1.id.ToString+"的进程已经完成\r\n";a = a + p1.ra;b = b + p1.rb;c = c + p1.rc;hready.RemoveAt0;}else{p1.state='W';hready1.Addp1;hready.RemoveAt0;}}//检测当前资源数目是否满足阻塞数组里进程的需求public void testblock{ArrayList hblock1 = new ArrayList;hblock1 = hblock;for int m = 0; m < hblock1.Count; m++{p1 = pcbhblock1m;if a - p1.ra >= 0 && b - p1.rb >= 0 && c - p1.rc >= 0{p1.state='W';hready.Addp1;a = a - p1.ra;b = b - p1.rb;c = c - p1.rc;listBox1.Items.Add"ID号为:"+p1.id + "的进程由阻塞队列转入就绪队列~~\r\n";hblock.RemoveAtm;m--;}}}//检测是否有新的进程产生;随机产生新进程public void testnew{int t;if r>0//r为随机产生的进程数目{t = random.Next9 + 1;if t <= 7{listBox1.Items.Add"\r\n有新的进程申请加入:~~";pcb jincheng = new pcb;jincheng.id = i++;jincheng.ra = random.Nexta + 1;jincheng.rb = random.Nextb + 1;jincheng.rc = random.Nextc + 1;jincheng.ntime = random.Next1; 5;jincheng.rtime = 0;listBox1.Items.Add"产生进程ID:" + jincheng.id;listBox1.Items.Add"所需A资源数目:" + jincheng.ra;listBox1.Items.Add"所需B资源数目:" + jincheng.rb;listBox1.Items.Add"所需C资源数目:" + jincheng.rc;listBox1.Items.Add"所需时间片数:" + jincheng.ntime;if a - jincheng.ra >= 0 && b - jincheng.rb >= 0 && c - jincheng.rc >= 0{a = a - jincheng.ra;b = b - jincheng.rb;c = c - jincheng.rc;jincheng.state = 'W';listBox1.Items.Add"进程状态为:" + jincheng.state;hready.Addjincheng;//加入就绪队列listBox1.Items.Add"资源满足新进程请求;该进程进入就绪队列~~\r\n";else{jincheng.state = 'B';hblock.Addjincheng;//加入阻塞队列listBox1.Items.Add"进程状态为:" + jincheng.state;listBox1.Items.Add"资源不满足新进程请求;该进程进入阻塞队列~~\r\n";}}}r = r - 1;}//系统三类资源变化情况的显示public void rescore//系统三类资源变化情况的显示{if a > a1 { textBox1.Text = a1.ToString; }if a < 0 { textBox1.Text = "0"; }if a >= 0 && a < a1 { textBox1.Text = a.ToString; }if b > b1 { textBox2.Text = b1.ToString; }if b < 0 { textBox2.Text = "0"; }if b >= 0 && b <= b1 { textBox2.Text = b.ToString; }if c > c1 { textBox3.Text = c1.ToString; }if c < 0 { textBox3.Text = "0"; }if c >= 0 && c <= c1 { textBox3.Text = c.ToString; }}//时间片轮转调度算法先来先服务FCFS算法public void runFcfs{if hready.Count>0{outputall;running;testblock;testnew;rescore;}else{timer1.Enabled = false;textBox1.Text = a1.ToString;textBox2.Text = b1.ToString;textBox3.Text = c1.ToString;listBox1.Items.Add"\r\n<<<<<<<<所有进程都已经运行结束>>>>>>>~\r\n";}//计时器触发时间片轮转调度算法private void timer1_Tickobject sender; EventArgs erunFcfs;}//开始模拟按钮单击执行函数private void button1_Clickobject sender; EventArgs e {runmain;button1.Enabled = false;textBox1.Enabled = false;textBox2.Enabled = false;textBox3.Enabled = false;textBox4.Enabled = false;textBox5.Enabled = false;textBox6.Enabled = false;textBox7.Enabled = false;textBox8.Enabled = false;textBox9.Enabled = false;}//清除屏幕按钮单击执行函数private void button2_Clickobject sender; EventArgs e {textBox1.Text = "";textBox2.Text = "";textBox3.Text = "";textBox4.Text = "";textBox5.Text = "";textBox6.Text = "";textBox7.Text = "";textBox8.Text = "";textBox9.Text = "";listBox1.Items.Clear;textBox4.Enabled = true;textBox5.Enabled = true;textBox6.Enabled = true;textBox7.Enabled = true;textBox8.Enabled = true;textBox9.Enabled = true;button1.Enabled = true;}//运行的主函数public void runmain{input;imer1.Enabled = true;3、运行界面和运行结果界面中;可以任意设定需要模拟的进程总数如5;初始化进程个数如3;还有A、B、C三类资源的总数如10、10、10..为了方便显示;还可以设定时间片的长度如500毫秒..除此之外;在运行过程中;所有的资源都是随机生成的;并且其中新进程的产生也是随机的;但是产生的进程总数不会多于开始设定的模拟的进程总数;以防止不断产生新进程;程序不断运行..在显示窗口的上方;还会实时显示资源的变化情况;方便对运行的观察..当运行结束后;可以通过工具栏中的显示选项中的保存结果按钮;将结果保存成txt文件格式;方便运行后的结果分析..五、心得体会本次实验;我的任务是设计一个允许n个进程并发运行的进程管理模拟系统..该系统包括有简单的进程控制、同步与通讯机构;系统在运行过程中能显示各进程的状态及有关参数的变化情况;从而观察诸进程的运行过程及系统的管理过程;我是用C写的;在我的电脑能够运行通过;虽不能尽善尽美;但也基本能实现老师的要求..两个星期的实验;虽然时间有点短;但我也收获不少;这次实验;加深了我对进程概念及进程管理的理解;比较熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施..也让我认识到自己的不足;操作系统的有些知识;我知道的还不多;没有掌握好;还需要多多学学;不断提升自己的能力..实验中;我们小组分工合作;共同学习;虽然在实验中遇到了一些问题;但在老师和同学的细心指导和热心帮助下解决了..同时;了解到团队精神的重要性;也为以后的学习和工作打下了坚实的基础;同时积累了宝贵的经验..。
windows操作系统实验报告
大学操作系统实验报告实验一进程控制与描述一、实验目的通过对Windows2000编程,进一步熟悉操作系统的基本概念,较好地理解Windows2000的结构。
通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解Windows2000进程的“一生”。
三、实验内容和步骤第一部分:Windows2000Professional下的GUI应用程序,使用V isualC++编译器创建一个GUI应用程序,代码中包括了WinMain()方法,该方法GUI类型的应用程序的标准入口点。
程序1-1Windows2000的GUI应用程序也可以利用任何其他文本编辑器键入程序代码,如果这样,例如使用WORD来键入和编辑程序,则应该注意什么问题?保存时,将文件保存为扩展名为*.cpp的C++源文件。
在程序1-1的GUI应用程序中,首先需要Windows.h头文件,以便获得传送给WinMain()和MessageBox()API 函数的数据类型定义。
接着的pragma指令指示编译器/连接器找到User32.LIB库文件并将其与产生的EXE文件连接起来。
这样就可以运行简单的命令行命令CLMsgBox.CPP来创建这一应用程序,如果没有pragma指令,则MessageBox()API 函数就成为未定义的了。
这一指令是V isualStudioC++编译器特有的。
接下来是WinMain()方法。
其中有四个由实际的低级入口点传递来的参数。
hInstance参数用来装入与代码相连的图标或位图一类的资源,无论何时,都可用GetModuleHandle()API函数将这些资源提取出来。
系统利用实例句柄来指明代码和初始的数据装在内存的何处。
句柄的数值实际上是EXE文件映像的基地址,通常为0x00400000。
下一个参数hPrevInstance是为向后兼容而设的,现在系统将其设为NULL。
应用程序的命令行(不包括程序的名称)是lpCmdLine参数。
进程控制实验报告
进程控制实验报告进程控制实验报告一、实验目的本实验旨在通过实际操作,深入理解进程控制的概念、原理和实现方式,掌握进程控制的技巧和方法,提升解决实际问题的能力。
二、实验原理进程控制是操作系统内核的重要功能之一,它负责协调和管理系统中多个进程的执行顺序和资源分配。
进程控制的主要任务包括创建和终止进程、进程切换和进程同步等。
本实验将通过具体的操作,学习和体验进程控制的过程和细节。
三、实验步骤1.实验准备(1)了解和熟悉实验室环境,包括计算机硬件配置、操作系统版本等信息。
(2)准备实验材料,包括相关文档、软件工具等。
(3)明确实验任务和目的,制定实验计划。
2.创建进程(1)打开实验环境,启动操作系统。
(2)使用编程语言(如C语言)编写一个简单的程序,该程序将创建一个新的进程。
(3)编译并运行程序,观察和记录进程的创建过程。
3.进程切换(1)编写一个程序,该程序将在两个进程之间进行切换。
(2)运行程序,观察和记录进程切换的过程和效果。
4.进程同步(1)使用信号量或其他同步机制实现两个进程的同步。
(2)运行程序,观察和记录进程同步的过程和效果。
5.进程终止(1)编写一个程序,该程序将终止一个指定的进程。
(2)运行程序,观察和记录进程终止的过程和效果。
6.实验总结与报告编写(1)总结实验过程和结果,梳理实验中的问题和解决方法。
(2)编写实验报告,包括实验目的、原理、步骤、结果分析等。
四、实验结果与分析通过本次实验,我们成功地创建了一个新的进程,并实现了进程之间的切换、同步和终止。
在实验过程中,我们深入理解了进程控制的概念、原理和实现方式,掌握了进程控制的技巧和方法。
同时,我们也遇到了一些问题,如进程创建失败、进程切换不成功等,但通过仔细分析问题原因并采取相应的解决方法,最终成功解决了这些问题。
通过本次实验,我们不仅学到了专业知识,也提高了解决实际问题的能力。
五、实验结论与建议本次实验让我们更加深入地理解了进程控制的相关知识,并掌握了进程控制的基本操作方法。
进程控制 实验报告
进程控制实验报告进程控制实验报告一、引言进程控制是操作系统中的重要概念,它涉及到进程的创建、调度、终止等方面。
本篇实验报告将介绍我们在进程控制实验中所进行的工作和实验结果。
二、实验目的本次实验的目的是通过编写程序,了解进程的创建、调度和终止过程,并掌握相关的系统调用和操作。
三、实验环境我们使用的实验环境是Linux操作系统,并使用C语言编写程序。
四、实验步骤1. 进程创建在实验中,我们编写了一个简单的程序,用于创建新的进程。
通过调用系统调用fork(),我们可以在父进程中创建一个子进程。
子进程是父进程的副本,它们共享一些资源,但有各自独立的执行空间。
2. 进程调度在实验中,我们使用了系统调用exec()来进行进程调度。
通过调用exec(),我们可以在一个进程中执行另一个可执行文件。
这样,原来的进程将被替换为新的进程,并开始执行新的程序。
3. 进程终止在实验中,我们使用了系统调用exit()来终止一个进程。
当一个进程执行完毕或者遇到错误时,可以调用exit()来结束自己的执行。
同时,exit()函数还可以传递一个整数值作为进程的返回值,供其他进程获取。
五、实验结果通过实验,我们成功地创建了多个进程,并进行了调度和终止操作。
我们观察到,创建的子进程在父进程的基础上执行,并且具有独立的执行空间。
在调度过程中,我们能够看到进程的切换和执行结果的输出。
在终止过程中,我们成功地结束了进程的执行,并获取了进程的返回值。
六、实验总结通过本次实验,我们深入了解了进程控制的相关概念和操作。
我们通过编写程序,实际操作了进程的创建、调度和终止过程。
这些实验结果对于我们理解操作系统的工作原理和进程管理机制具有重要意义。
七、实验感想本次实验让我们深刻认识到进程控制在操作系统中的重要性。
进程的创建、调度和终止是操作系统能够高效运行的基础。
通过实验,我们不仅掌握了相关的系统调用和操作,还加深了对操作系统原理的理解。
八、实验改进在实验中,我们可以进一步扩展功能,例如实现进程间的通信和同步机制。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一、进程控制实验1.1 实验目的加深对于进程并发执行概念的理解。
实践并发进程的创建和控制方法。
观察和体验进程的动态特性。
进一步理解进程生命期期间创建、变换、撤销状态变换的过程。
掌握进程控制的方法,了解父子进程间的控制和协作关系。
练习Linux 系统中进程创建与控制有关的系统调用的编程和调试技术。
1.2 实验说明1)与进程创建、执行有关的系统调用说明进程可以通过系统调用fork()创建子进程并和其子进程并发执行.子进程初始的执行映像是父进程的一个复本.子进程可以通过exec()系统调用族装入一个新的执行程序。
父进程可以使用wait()或waitpid()系统调用等待子进程的结束并负责收集和清理子进程的退出状态。
fork()系统调用语法:#include <unistd.h> pid_tfork(void);fork 成功创建子进程后将返回子进程的进程号,不成功会返回-1.exec 系统调用有一组6 个函数,其中示例实验中引用了execve 系统调用语法:#include <unistd.h>int execve(const char *path, const char *argv[], const char * envp[]); path 要装入的新的执行文件的绝对路径名字符串.argv[] 要传递给新执行程序的完整的命令参数列表(可以为空).envp[] 要传递给新执行程序的完整的环境变量参数列表(可以为空).Exec 执行成功后将用一个新的程序代替原进程,但进程号不变,它绝不会再返回到调用进程了。
如果exec 调用失败,它会返回-1。
wait() 系统调用语法:#include <sys/types.h>#include <sys/wait.h> pid_twait(int *status);pid_t waitpid(pid_t pid,int *status,int option); status 用于保留子进程的退出状态pid 可以为以下可能值:-1 等待所有PGID 等于PID 的绝对值的子进程1 等待所有子进程0 等待所有PGID 等于调用进程的子进程>0 等待PID 等于pid 的子进程option 规定了调用waitpid 进程的行为:WNOHANG 没有子进程时立即返回WUNTRACED 没有报告状态的进程时返回wait 和waitpid 执行成功将返回终止的子进程的进程号,不成功返回-1。
getpid()系统调用语法:#include <sys/types.h>#include <unistd.h> pid_tgetpid(void);pid_t getppid(void);getpid 返回当前进程的进程号,getppid 返回当前进程父进程的进程号2)与进程控制有关的系统调用说明可以通过信号向一个进程发送消息以控制进程的行为。
信号是由中断或异常事件引发的,如:键盘中断、定时器中断、非法内存引用等。
信号的名字都以SIG 开头,例如SIGTERM、SIGHUP。
可以使用kill -l 命令查看系统当前的信号集合。
信号可在任何时间发生,接收信号的进程可以对接收到的信号采取3种处理措施之一:•忽略这个信号•执行系统默认的处理•捕捉这个信号做自定义的处理信号从产生到被处理所经过的过程:产生(generate)-> 挂起(pending)-> 派送(deliver)-> 部署(disposition) 或忽略(igore)一个信号集合是一个C 语言的sigset_t 数据类型的对象,sigset_t 数据类型定义在<signal.h>中。
被一个进程忽略的所有信号的集合称为一个信号掩码(mask)。
从程序中向一个进程发送信号有两种方法:调用shell 的kill 命令,调用kill系统调用函数。
kill能够发送除杀死一个进程(SIGKILL、SIGTERM、SIGQUIT)之外的其他信号,例如键盘中断(Ctrl+C)信号SIGINT,进程暂停(Ctrl+Z)信号SIGTSTP 等等。
调用Pause 函数会令调用进程的执行挂起直到一个任意信号到来后再继续运行。
调用sleep 函数会令调用进程的执行挂起睡眠指定的秒数或一个它可以响应的信号到来后继续执行。
每个进程都能使用signal 函数定义自己的信号处理函数,捕捉并自行处理接收的除SIGSTOP 和SIGKILL 之外的信号。
以下是有关的系统调用的语法说明。
kill 系统调用语法:#include <sys/types.h>#include <signal.h>int kill(pid_t pid, int sig);pid 接收信号的进程号signal 要发送的信号kill 发送成功返回接收者的进程号,失败返回-1。
pause 系统调用语法:#include <unistd.h> intpause(void);pause 挂起调用它的进程直到有任何信号到达。
调用进程不自定义处理方法,则进行信号的默认处理。
只有进程自定义了信号处理方法捕获并处理了一个信号后,pause 才会返回调进程。
pause 总是返回-1,并设置系统变量errno 为EINTR。
sleep 系统调用语法:#include <unistd.h>unsigned int sleep(unsigned int seconds);seconds 指定进程睡眠的秒数如果指定的秒数到,sleep 返回0。
signal 系统调用语法为:#include <signal.h> typedef void(*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);signum 要捕捉的信号handler 进程中自定义的信号处理函数名signal 调用成功会返回信号处理函数的返回值,不成功返回-1,并设置系统变量errno 为SIG_ERR。
1.3 示例实验以下实验示例程序应实现一个类似子shell 子命令的功能,它可以从执行程序中启动另一个新的子进程并执行一个新的命令和其并发执行.1)打开一终端命令行窗体,新建一个文件夹,在该文件夹中建立以下名为pctl.c 的C语言程序:/**Filename : pctl.c*copyright : (C) 2006 by zhanghonglie*Function : 父子进程的并发执行*/#include "pctl.h"int main(int argc, char *argv[]){ int i;int pid; //存放子进程号int status; //存放子进程返回状态char *args[] ={"/bin/ls","-a",NULL}; //子进程要缺省执行的命令signal(SIGINT,(sighandler_t)sigcat);//注册一个本进程处理键盘中断的函数pid=fork() ; //建立子进程if(pid<0) // 建立子进程失败?{printf("Create Process fail!\n"); exit(EXIT_FAILURE);}if(pid == 0) // 子进程执行代码段{//报告父子进程进程号printf("I am Child process %d\nMy father is %d\n",getpid(),getppid());pause(); //暂停,等待键盘中断信号唤醒//子进程被键盘中断信号唤醒继续执行printf("%d child will Running: \n",getpid()); // if(argv[1] != NULL){//如果在命令行上输入了子进程要执行的命令//则执行输入的命令for(i=1; argv[i] != NULL; i++) printf("%s ",argv[i]);printf("\n");//装入并执行新的程序status = execve(argv[1],&argv[1],NULL);} else{//如果在命令行上没输入子进程要执行的命令//则执行缺省的命令for(i=0; args[i] != NULL; i++) printf("%s ",args[i]); printf("\n");//装入并执行新的程序status = execve(args[0],args,NULL);}}else //父进程执行代码段{printf("\nI am Parent process %d\n",getpid()); //报告父进程进程号if(argv[1] != NULL){ //如果在命令行上输入了子进程要执行的命令//则父进程等待子进程执行结束printf("%d Waiting for child done.\n\n",pid); waitpid(pid,&status,0); //等待子进程结束printf("\nMy child exit! status = %d\n\n",status);} else{//如果在命令行上没输入子进程要执行的命令//唤醒子进程,与子进程并发执行不等待子进程执行结束,if(kill(pid,SIGINT) >= 0)printf("%d Wakeup %d child.\n",getpid(),pid) ; printf("%d don't Wait for child done.\n\n",getpid());} }return EXIT_SUCCESS;}2)再建立以下名为pctl.h 的C 语言头文件:#include <sys/types.h>#include <wait.h>#include <unistd.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>//进程自定义的键盘中断信号处理函数typedef void (*sighandler_t) (int); void sigcat(){printf("%d Process continue\n",getpid());}3)建立以下项目管理文件Makefilehead = pctl.h srcs = pctl.c objs = pctl.o opts =-g -call: pctlpctl: $(objs) gcc $(objs) -o pctl pctl.o:$(srcs) $(head) gcc $(opts) $(srcs) clean:rm pctl *.o4)输入make 命令编译连接生成可执行的pctl 程序$g makegcc -g -c pctl.cgcc pctl.o -o pctl5)执行pctl 程序(注意进程号是动态产生的,每次执行都不相同)$ ./pctlI am Child process 4113My father is 4112I am Parent process 4112 Wakeup 4113 child.4112don't Wait for child done.4113Process continue4113 child will Running: /bin/ls -a. .. Makefile pctl pctl.c pctl.h pctl.o$以上程序的输出说明父进程4112 创建了一个子进程4113,子进程执行被暂停。