实验2-进程控制与通信管理

实验2-进程控制与通信管理
实验2-进程控制与通信管理

年级11级专业计算机科学与技术班级五班

组号12组实验室9#205 日期2014/05/17 实验

名称

实验二、进程控制与通信管理

实验内容

分项内容

实验级别

1、Linux 系统常用进程管理命令的使用操作系统观察级

2、Linux 系统常用进程创建与管理的系统调用原码阅读与系统编程级

3、Windows平台常用进线程控制API 原码阅读与系统编程级

4、进程同步与互斥控制(读者写者、一家人吃苹果桔子、

哲学家吃饭)

码阅读与系统编程级

5、简单进程通信(管道、消息缓冲、邮件槽等)

(原码阅读与系统编程

级)

小组成员

姓名学号组内分工自我评分教师评分

独立完成实验二(1)良好

独立完成实验二(2)良好

独立完成实验二(3)良好

独立完成实验二(4)良好

独立完成实验二(5)良好

教师签名:

年月日

实验分项1 1、Linux 系统常用进程管理命令的使用2、Linux 系统常用进程创建与管理的系统调用3、Windows平台常用进线程控制API 4、进程同步与互斥控制5、简单进程通信

实验目的一、实验目的:

1、加深对进程概念的理解,明确进程和程序的区别。

2、进一步认识并发执行的实质。

3、分析进程争用资源的现象,学习解决进程互斥的方法。

验要求具体题目:进程创建、进程控制

系统平台:Linux/Windows操作系统

实验原理步骤(算法流程)二、实验原理

1.Linux 系统常用进程管理命令

(1)at命令:定时运行命令

让系统在两天后的17:30执行文件data中指定的作业,使用命令:

#at -f data 15:30 +2 days

(2)bg命令后台运行命令

如果要将一个大目录的文件进行排序后,将结果输入到一个文件中,可以使用命令:#du -a / | sort -rn > /tmp/du.sorted

(3)Fg挂起程序

使用fg命令时,要加入后台任务号码,如果不加任何号码,则所变动的均是当前任务。

#du -a / | sort -rn > /tmp/du.sorted &[1] 237

#fg 1

(4)Jobs显示后台程序

先把两个进程放在系统后台运行,然后使用jobs命令查看后台任务的执行情况:

#du -a /etc > user.data &

[1] 233

# find / -name core -type f -ls > core.data &

[2] 234

#jobs -l

[1] + 237 Running du -a /etc > user.data

[2] - 238 Running find / -name core -type f -ls >

core.data

(5)kill命令杀掉进程

命令执行过程如果出错,用户可用"kill"来结束任务。对于在后台运行的进程,

可以使用kill命令终止:

#du -a / | sort -rn > /tmp/du.sorted &

[1] 237

#kill 237

(6)nice命令改变权限优先级

将ls命令的优先序加1并执行,将结果输入文件1.txt:

# nice -n 1 ls >1.txt

(7)renice命令修改优先级

将进程PID为987及32的进程与进程拥有者为daemon及root的优先级别号加1:#renice +1 987 -u daemon root -p 32

(8)sleep命令暂停进程

下面的命令使进程先暂停60秒,然后查看哪个用户登录到系统中:

#sleep 60; who

2、进程同步与互斥控制(数据同步),原理如下:

(1)、设置全局变量:int ticket=100;互斥量:HANDLE hMutex;

(2)、创建互斥信号量ticket:hMutex=CreateMutex(NULL,TRUE,"ticket");

(3)、用WaitForSingleObject(hMutex,INFINITE);捕获互斥信号量hMutex

(4)、用ReleaseMutex(hMutex);释放互斥量的使用权

3、通过邮件槽实现简单进程通信,原理如下:

(1)、油槽服务器:

1)hMailslot=CreateMailslot("\\\\.\\mailslot\\MyMailslot",0,

MAILSLOT_WAIT_FOREVER,NULL);//创建一个邮路。

2)ReadFile(hMailslot,buf,100,&dwRead,NULL);//读取邮路数据

3)CloseHandle(hMailslot);//关闭油槽

(2)、油槽客户端:

1)hMailslot=CreateFile("\\\\.\\mailslot\\MyMailslot",GENERIC_WRITE, FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

//创建油槽文件

2)WriteFile(hMailslot,buf,strlen(buf)+1,&dwWrite,NULL);//写入数据

3)CloseHandle(hMailslot);//关闭油槽

实验源代码如下:

1、进程同步与互斥控制(数据同步):

#include "stdafx.h"

#include

#include"iostream"

using namespace std;

int index =0;

int ticket=100;

HANDLE hMutex;

DWORD WINAPI Fun1Proc(LPVOID lpParameter)

{

while(TRUE)

{

WaitForSingleObject(hMutex,INFINITE);

if(ticket>0)

{

cout<<"thread1 sell ticket :"<

}

else

break;

ReleaseMutex(hMutex);

}

return 0;

}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)

{

while(TRUE)

{

WaitForSingleObject(hMutex,INFINITE);

if(ticket>0)

{

cout<<"thread2 sell ticket :"<

}

else

break;

ReleaseMutex(hMutex);

}

return 0;

}

int _tmain(int argc, _TCHAR* argv[])

{

HANDLE hTread1;

HANDLE hTread2;

hTread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);

hTread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);

CloseHandle(hTread1);

CloseHandle(hTread2);

hMutex=CreateMutex(NULL,TRUE,"ticket");

if(hMutex)

{

if(ERROR_ALREADY_EXISTS==GetLastError())

{

cout<<"Only one instance can run!"<

return 0;

}

}

ReleaseMutex(hMutex);

ReleaseMutex(hMutex);

Sleep(10000);

return 0;

}

2、邮件槽进程通信:

1)油槽服务器:(关键代码段)

void C油槽客户端Dlg::OnSend()

{

// TODO: 在此添加控件通知处理程序代码

HANDLE hMailslot;

hMailslot=CreateFile("\\\\.\\mailslot\\MyMailslot",GENERIC_WRITE,FILE_SHARE_ READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INV ALID_HANDLE_V ALUE==hMailslot)

{

MessageBox("打开油槽失败!");

return;

}

CString str;

char buf[100];

m_edit.GetWindowText(str);

strcpy_s(buf,str);

DWORD dwWrite;

if(!WriteFile(hMailslot,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

CloseHandle(hMailslot);

return;

}

CloseHandle(hMailslot);

}

2)油槽客户端:(关键代码段)

void C油槽客户端Dlg::OnSend()

{

// TODO: 在此添加控件通知处理程序代码

HANDLE hMailslot;

hMailslot=CreateFile("\\\\.\\mailslot\\MyMailslot",GENERIC_WRITE,FILE_SHARE_

READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if(INV ALID_HANDLE_V ALUE==hMailslot)

{

MessageBox("打开油槽失败!");

return;

}

CString str;

char buf[100];

m_edit.GetWindowText(str);

strcpy_s(buf,str);

DWORD dwWrite;

if(!WriteFile(hMailslot,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("写入数据失败!");

CloseHandle(hMailslot);

return;

}

CloseHandle(hMailslot);

}

(写不完时,可另加附页。)

实验结果及分析三、实验结果:

1、实验截图:

2-1进程控制达到数据同步处理截图

2-2 油槽通信控制面板截图

2-3 油槽-服务器截图2-4 油槽-客户端截图2-5 发送-接受效果截图

2、结果分析:

1)、ls 命令列出了指定目录下的文件名和目录名,参数-l要求显示文件或目录的详细信息,例如类型、访问权限、连接数、拥有者等。

在Linux中,用户通过利用fork创建的进程来与原进程运行相同的程序代码,为了使新进程运行新的程序,用户可以使用系统调用exec来装入一个新的程序到当前进程的地址空间,如果exec调用成功,系统开始执行新程序,永远不会返回原来的程序。

2)、进程同步与互斥控制,能有效的控制全局变量在某一进程执行过程中唯一被访问。在多线程程序中容易出现共享资源因时间片到期而终止访问,这样就很容易出现数据的错乱。假如全局变量未火车票;对于线程函数(FunProc1、FunProc2),在访问全局变量ticket时,ticket自减一。如果在线程函数1(FunProc1)访问ticket,还没有来得及自减一就因时间片到期而被线程函数2(FunProc2)抢占访问,然后自减一。这样就造成了资源数据不一致,从而产生很危险的后果。

本实验通过设置互斥信号量从而达到线程之间对共享资源的同步访问,以此还可以实现进程同步中的读者/写者问题。

3)、由于油槽是单向通信机制,所以只能通过创建油槽服务器进程读取数据,打开油槽客户端进程写入数据。如果只打开油槽服务器,创建读取数据进程而没有打开客户端就会导致服务器进入无限等代状态,造成程序崩溃。

在创建进程句柄后要记得释放句柄,不然会产生不良后果。

心得体会

在了解了操作系统中进程间的通信的方式我们使用了邮槽实现了简单的进程间的通信,在实际的应用中,进程间的通信往往是十分重要的,我们可以使用其它的应用程序提供的信息,使我们自己的程序开发更为完善,在进程间的通信中,我们还可以使用管道技术,管道技术又分为命名管道和匿名管道,匿名管道是实现本机之见的进程通信,命名管道很好的解决了,客户端和服务器之间的通信,另一种实现服务器和客户端之间的通信是邮槽,通过该实验更加深入理解了操作系统的通信方式——邮槽通信以及信息通信。真正体会从课本上学到的东西是有限了,要提高自己的技术水平,还是得实践去努力。

Linux进程间通信(2)实验报告

实验六:Linux进程间通信(2)(4课时) 实验目的: 理解进程通信原理;掌握进程中信号量、共享内存、消息队列相关的函数的使用。实验原理: Linux下进程通信相关函数除上次实验所用的几个还有: 信号量 信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。要调用的第一个函数是semget,用以获得一个信号量ID。 int semget(key_t key, int nsems, int flag); key是IPC结构的关键字,flag将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。 semctl函数用来对信号量进行操作。 int semctl(int semid, int semnum, int cmd, union semun arg); 不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。 semop函数自动执行信号量集合上的操作数组。 int semop(int semid, struct sembuf semoparray[], size_t nops); semoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。 ftok原型如下: key_t ftok( char * fname, int id ) fname就是指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255)。 当成功执行的时候,一个key_t值将会被返回,否则-1 被返回。 共享内存 共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在不同的进程间复制。通常由一个进程创建一块共享内存区,其余进程对这块内存区进行读写。首先要用的函数是shmget,它获得一个共享存储标识符。 #include #include #include int shmget(key_t key, int size, int flag); 当共享内存创建后,其余进程可以调用shmat()将其连接到自身的地址空间中。 void *shmat(int shmid, void *addr, int flag); shmid为shmget函数返回的共享存储标识符,addr和flag参数决定了以什么方式来确定连接的地址,函数的返回值即是该进程数据段所连接的实际地

实验二进程管理

实验二进程管理 (一)实验目的或实验原理 1.加深对进程概念的理解,明确进程和程序的区别。 2.进一步认识并发执行的实质。 3.分析进程竞争资源现象,学习解决进程互斥的方法。 4.了解Linux系统中进程通信的基本原理。 (二)实验内容 1.进程的创建。 2.进程的控制。 3.①编写一段程序,使其现实进程的软中断通信。 要求:使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按DEL键);当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child Processll is Killed by Parent! Child Processl2 is Killed by Parent! 父进程等待两个子进程终止后,输出如下的信息后终止 Parent Process is Killed! ②在上面的程序中增加语句signal (SIGNAL, SIG-IGN) 和signal (SIGQUIT, SIG-IGN), 观察执行结果,并分析原因。 4.进程的管道通信。 编制一段程序,实现进程的管理通信。 使用系统调用pipe()建立一条管道线;两个子进程P1和P2分别向管道中写一句话: Child 1 is sending a message! Child 2 is sending a message! 而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。 要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。 实验2 指导 [实验内容] 1.进程的创建 〈任务〉 编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 〈程序〉 #include<> main() { int p1,p2; if(p1=fork()) /*子进程创建成功*/ p utchar('b'); else { if(p2=fork()) /*子进程创建成功*/

windows进程管理实验报告

实验报告 课程名称:操作系统 实验项目:windows进程管理 姓名: 专业:计算机科学与技术 班级: 学号:

计算机科学与技术学院 计算机系 2019 年 4 月 23 日

实验项目名称: windows进程管理 一、实验目的 1. 学习windows系统提供的线程创建、线程撤销、线程同步等系统调用; 2. 利用C++实现线程创建、线程撤销、线程同步程序; 3. 完成思考、设计与练习。 二、实验用设备仪器及材料 1. Windows 7或10, VS2010及以上版本。 三、实验内容 1 线程创建与撤销 写一个windows控制台程序(需要MFC),创建子线程,显示Hello, This is a Thread. 然后撤销该线程。 相关系统调用: 线程创建: CreateThread() 线程撤销: ExitThread() 线程终止: ExitThread(0) 线程挂起: Sleep() 关闭句柄: CloseHandle() 参考代码: ; } 运行结果如图所示。 完成以下设计题目: 1. 向线程对应的函数传递参数,如字符串“hello world!”,在线程中显示。 2. 如何创建3个线程A, B, C,并建立先后序执行关系A→B→C。

实验内容2 线程同步 完成父线程和子线程的同步。父线程创建子线程后进入阻塞状态,子线程运行完毕后再唤醒。 相关系统调用: 等待对象 WaitForSingleObject(), WaitForMultipleObjects(); 信号量对象 CreateSemaphore(), OpenSemaphore(), ReleaseSemaphore(); HANDLE WINAPI CreateSemaphore( _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes _In_ LONG lInitialCount, _In_ LONG lMaximumCount, _In_opt_ LPCTSTR lpName ); 第一个参数:安全属性,如果为NULL则是默认安全属性 第二个参数:信号量的初始值,要>=0且<=第三个参数 第三个参数:信号量的最大值 第四个参数:信号量的名称 返回值:指向信号量的句柄,如果创建的信号量和已有的信号量重名,那么返回已经存在的信号量句柄参考代码: n"); rc=ReleaseSemaphore(hHandle1,1,NULL); err=GetLastError(); printf("Release Semaphore err=%d\n",err); if(rc==0) printf("Semaphore Release Fail.\n"); else printf("Semaphore Release Success. rc=%d\n",rc); } 编译运行,结果如图所示。

实验四父子进程通信

Linux进程通信 【实验程序及分析】 2. 父子进程同步 修改父进程创建子进程程序,使用exit()和wait()实现父子进程同步,其同步方式为父进程等待子进程的同步,即:子进程循环输出5次,然后父进程再循环输出5次。给出源程序代码和运行结果。 wait的函数原型是: #include /* 提供类型pid_t的定义 */ #include pid_t wait(int *status); 返回值:如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno中。 进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程, wait 就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。 参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就象下面这样: pid = wait(NULL); 如果成功,wait会返回被收集的子进程的进程ID,如果调用进程没有子进程,调用就会失败,此时wait返回-1。 通过执行系统调用exit来终止一个进程。进程可以显示的调用exit系统调用来终止一个进程,也可以通过在程序结束时的return来实现。 调用exit方式如下: exit(status); status是返回给父进程的终止code。当一个进程exit后,这个进程处于zombie state。一般情况下exit(0)表示正常退出,exit(1),exit(-1)为异常退

进程管理实验报告

实验2过程管理实验报告学生号姓名班级电气工程系过程、过程控制块等基本原理过程的含义:过程是程序运行过程中对数据集的处理,以及由独立单元对系统资源的分配和调度。在不同的数据集上运行程序,甚至在同一数据集上运行多个程序,是一个不同的过程。(2)程序状态:一般来说,一个程序必须有三种基本状态:就绪、执行和阻塞。然而,在许多系统中,过程的状态变化可以更好地描述,并且增加了两种状态:新状态和终端状态。1)就绪状态,当一个进程被分配了除处理器(CPU)以外的所有必要资源时,只要获得了处理器,进程就可以立即执行。此时,进程状态称为就绪状态。在系统中,多个进程可以同时处于就绪状态。通常,这些就绪进程被安排在一个或多个队列中,这些队列称为就绪队列。2)一旦处于就绪状态的进程得到处理器,它就可以运行了。进程的状态称为执行状态。在单处理器系统中,只有一个进程在执行。在多处理器系统中,可能有多个进程在执行中。3)阻塞状态由于某些事件(如请求输入和输出、额外空间等),执行进程被挂起。这称为阻塞状态,也称为等待状态。通常,处于阻塞状态的进程被调度为-?这个队列称为阻塞队列。4)新状态当一个新进程刚刚建立并且还没有放入就绪队列中时,它被称为新状态。5)终止状态是

什么时候-?进程已正常或异常终止,操作系统已将其从系统队列中删除,但尚未取消。这就是所谓的终结状态。(3)过程控制块是过程实体的重要组成部分,是操作系统中最重要的记录数据。控制块PCB记录操作系统描述过程和控制过程操作所需的所有信息。通过PCB,一个不能独立运行的程序可以成为一个可以独立运行的基本单元,并且可以同时执行一个进程。换句话说,在进程的整个生命周期中,操作系统通过进程PCB管理和控制并发进程。过程控制块是系统用于过程控制的数据结构。系统根据进程的PCB来检测进程是否存在。因此,进程控制块是进程存在的唯一标志。当系统创建一个进程时,它需要为它创建一个PCB;当进程结束时,系统回收其PCB,进程结束。过程控制块的内容过程控制块主要包括以下四个方面的信息。过程标识信息过程标识用于对过程进行标识,通常有外部标识和内部标识。外部标识符由流程的创建者命名。通常是一串字母和数字。当用户访问进程时使用。外部标识符很容易记住。内部标识符是为了方便系统而设置的。操作系统为每个进程分配一个唯一的整数作为内部标识符。通常是进程的序列号。描述性信息(process scheduling message)描述性信息是与流程调度相关的一些有关流程状态的信息,包括以下几个方面。流程状态:表

实验一 和实验二

实验一熟悉Windows2000/XP中的进程和线程 一、实验目的 1、熟悉Windows2000/XP中任务管理器的使用。 2、通过任务管理器识别操作系统中的进程和线程的相关信息。 3、掌握利用spy++.exe来察看Windows中各个任务的更详细信息。 二、实验理论基础 1、实验理论基础: (1)操作系统中的进程和线程的概念; (2)进程PCB的各项指标含意; (3)操作系统中的进程和线程的概念; (4)进程的各种控制; 三、实验内容与步骤 1、启动操作系统自带的任务管理器: 方法:直接按组合键Ctrl+Alt+Del,或者是在点击任务条上的“开始”“运行”,并输入“taskmgr.exe”。如下图所示:

2、调整任务管理器的“查看”中的相关设置,显示关于进程的以下各项信息, 并完成下表(填满即可): 表一:统计进程的各项主要信息

3、从桌面启动办公软件“Word”,在任务管理器中找到该软件的登记,并将其结 束掉。再从任务管理器中分别找到下列程序:winlogon.exe、lsass.exe、csrss.exe、smss.exe,试着结束它们,观察到的反应是无法中止进程,原因是该程序为关键系统进程,任务管理器无法结束进程。 4、在任务管理器中找到进程“explorer.exe”,将之结束掉,并将桌面上你打开 的所有窗口最小化,看看你的计算机系统起来什么样的变化桌面所有的快捷图标消失,任务栏消失、得到的结论是这个进程用于显示桌面上的图标和开始菜单(说出explorer.exe进程的作用)。 5、运行“spy++.exe”应用软件,点击按钮“”,切换到进程显示栏上,查看进程“explorer.exe”的各项信息,并填写下表: 表二:统计线程的各项信息 进程:explorer.exe 中的各个线程

操作系统实验二(进程管理)

操作系统进程管理实验 实验题目: (1)进程的创建编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察记录屏幕上的显示结果,并分析原因。 (2)进程的控制修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕上出现的现象,并分析原因。 (3)编制一段程序,使其实现进程的软中断通信。要求:使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按Del键);当捕捉到中断信号后,父进程调用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Child process 1 is killed by parent! Child process 2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止:Parent process is killed! 在上面的程序中增加语句signal(SIGINT, SIG_IGN)和signal(SIGQUIT, SIG_IGN),观察执行结果,并分析原因。 (4)进程的管道通信编制一段程序,实现进程的管道通信。使用系统调用pipe( )建立一条管道线;两个进程P1和P2分别向管道各写一句话:Child 1 is sending a message! Child 2 is sending a message! 而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。 实验源程序及报告: (1)、进程的创建 #include int main(int argc, char *argv[]) { int pid1,pid2; /*fork first child process*/ if ( ( pid1=fork() ) < 0 ) { printf( "ProcessCreate Failed!"); exit(-1); }

进程管理实验报告

进程的控制 1 .实验目的 通过进程的创建、撤消和运行加深对进程概念和进程并发执行的理解,明确进程与程序之间的区别。 【答:进程概念和程序概念最大的不同之处在于: (1)进程是动态的,而程序是静态的。 (2)进程有一定的生命期,而程序是指令的集合,本身无“运动”的含义。没有建立进程的程序不能作为1个独立单位得到操作系统的认可。 (3)1个程序可以对应多个进程,但1个进程只能对应1个程序。进程和程序的关系犹如演出和剧本的关系。 (4)进程和程序的组成不同。从静态角度看,进程由程序、数据和进程控制块(PCB)三部分组成。而程序是一组有序的指令集合。】2 .实验内容 (1) 了解系统调用fork()、execvp()和wait()的功能和实现过程。 (2) 编写一段程序,使用系统调用fork()来创建两个子进程,并由父进程重复显示字符串“parent:”和自己的标识数,而子进程则重复显示字符串“child:”和自己的标识数。 (3) 编写一段程序,使用系统调用fork()来创建一个子进程。子进程通过系统调用execvp()更换自己的执行代码,新的代码显示“new

program.”。而父进程则调用wait()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。 3 .实验步骤 (1)gedit创建进程1.c (2)使用gcc 1.c -o 1编译并./1运行程序1.c #include #include #include #include void mian(){ int id; if(fork()==0) {printf(“child id is %d\n”,getpid()); } else if(fork()==0) {printf(“child2 id %d\n”,getpid()); } else {id=wait(); printf(“parent id is %d\n”,getpid()); }

进程同步与通信作业习题与答案

第三章 一.选择题(50题) 1.以下_B__操作系统中的技术是用来解决进程同步的。 A.管道 B.管程 C.通道 2.以下_B__不是操作系统的进程通信手段。 A.管道 B.原语 C.套接字 D.文件映射 3.如果有3个进程共享同一程序段,而且每次最多允许两个进程进入该程序段,则信号量的初值应设置为_B__。 4.设有4个进程共享一个资源,如果每次只允许一个进程使用该资源,则用P、V操作管理时信号量S的可能取值是_C__。 ,2,1,0,-1 ,1,0,-1,-2 C. 1,0,-1,-2,-3 ,3,2,1,0 5.下面有关进程的描述,是正确的__A__。 A.进程执行的相对速度不能由进程自己来控制 B.进程利用信号量的P、V 操作可以交换大量的信息 C.并发进程在访问共享资源时,不可能出现与时间有关的错误 、V操作不是原语操作 6.信号灯可以用来实现进程之间的_B__。 A.调度 B.同步与互斥 C.同步 D.互斥 7.对于两个并发进程都想进入临界区,设互斥信号量为S,若某时S=0,表示_B__。 A.没有进程进入临界区 B.有1个进程进入了临界区 C. 有2个进程进入了临界区 D. 有1个进程进入了临界区并且另一个进程正等待进入 8. 信箱通信是一种_B__方式 A.直接通信 B.间接通信 C.低级通信 D.信号量 9.以下关于临界区的说法,是正确的_C__。

A.对于临界区,最重要的是判断哪个进程先进入 B.若进程A已进入临界区,而进程B的优先级高于进程A,则进程B可以 打断进程A而自己进入临界区 C. 信号量的初值非负,在其上只能做PV操作 D.两个互斥进程在临界区内,对共享变量的操作是相同的 10. 并发是指_C__。 A.可平行执行的进程 B.可先后执行的进程 C.可同时执行的进程 D.不可中断的进程 11. 临界区是_C__。 A.一个缓冲区 B.一段数据区 C.一段程序 D.栈 12.进程在处理机上执行,它们的关系是_C__。 A.进程之间无关,系统是封闭的 B.进程之间相互依赖相互制约 C.进程之间可能有关,也可能无关 D.以上都不对 13. 在消息缓冲通信中,消息队列是一种__A__资源。 A.临界 B.共享 C.永久 D.可剥夺 14. 以下关于P、V操作的描述正确的是__D_。 A.机器指令 B. 系统调用 C.高级通信原语 D.低级通信原语 15.当对信号量进行V源语操作之后,_C__。 A.当S<0,进程继续执行 B.当S>0,要唤醒一个就绪进程 C. 当S<= 0,要唤醒一个阻塞进程 D. 当S<=0,要唤醒一个就绪 16.对临界区的正确论述是__D_。 A.临界区是指进程中用于实现进程互斥的那段代码 B. 临界区是指进程中用于实现进程同步的那段代码 C. 临界区是指进程中用于实现进程通信的那段代码 D. 临界区是指进程中访问临界资源的那段代码 17. __A__不是进程之间的通信方式。 A.过程调用 B.消息传递 C.共享存储器 D.信箱通信 18. 同步是指进程之间逻辑上的__A__关系。

进程间通信实验报告

进程间通信实验报告 班级:10网工三班学生姓名:谢昊天学号:1215134046 实验目的和要求: Linux系统的进程通信机构 (IPC) 允许在任意进程间大批量地交换数据。本实验的目的是了解和熟悉Linux支持的消息通讯机制及信息量机制。 实验内容与分析设计: (1)消息的创建,发送和接收。 ①使用系统调用msgget (), msgsnd (), msgrev (), 及msgctl () 编制一长度为1k 的消息的发送和接收程序。 ②观察上面的程序,说明控制消息队列系统调用msgctl () 在此起什么作用? (2)共享存储区的创建、附接和段接。 使用系统调用shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序。(3)比较上述(1),(2)两种消息通信机制中数据传输的时间。 实验步骤与调试过程: 1.消息的创建,发送和接收: (1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。 (2)在SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER 。SERVER每接收到一个消息后显示一句“(server)received”。 (3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,既是 SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”。 (4)父进程在 SERVER和 CLIENT均退出后结束。 2.共享存储区的创建,附接和断接: (1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。 (2)SERVER端建立一个KEY为75的共享区,并将第一个字节置为-1。作为数据空的标志.等待其他进程发来的消息.当该字节的值发生变化时,表示收到了该消息,进行处理.然后再次把它的值设为-1.如果遇到的值为0,则视为结束信号,取消该队列,并退出SERVER.SERVER 每接收到一次数据后显示”(server)received”. (3)CLIENT端建立一个为75的共享区,当共享取得第一个字节为-1时, Server端空闲,可发送请求. CLIENT 随即填入9到0.期间等待Server端再次空闲.进行完这些操作后, CLIENT退出. CLIENT每发送一次数据后显示”(client)sent”. (4)父进程在SERVER和CLIENT均退出后结束。 实验结果: 1.消息的创建,发送和接收: 由 Client 发送两条消息,然后Server接收一条消息。此后Client Server交替发送和接收消息。最后一次接收两条消息。Client 和Server 分别发送和接收了10条消息。message 的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象。在多次send message 后才 receive message.这一点有助于理解消息转送的实现机理。

操作系统实验报告--实验一--进程管理

实验一进程管理 一、目的 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。 二、实验内容及要求 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; //进程ID public 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.Parse(textBox4.Text); n = int.Parse(textBox5.Text); a = int.Parse(textBox6.Text); b = int.Parse(textBox7.Text); c = int.Parse(textBox8.Text); a1 = a; b1 = b; c1 = c; r = m - n; time1Inteval = int.Parse(textBox9.Text); timer1.Interval = time1Inteval; for (i = 1; i <= n; i++) { pcb jincheng = new pcb(); jincheng.id = i; jincheng.ra = (random.Next(a) + 1); jincheng.rb = (random.Next(b) + 1); jincheng.rc = (random.Next(c) + 1); jincheng.ntime = (random.Next(1, 5)); jincheng.rtime = 0;

第3章 进程同步与通信 练习题答案

第3章进程同步与通信练习题 (一)单项选择题 1.临界区是指( )。 A.并发进程中用于实现进程互斥的程序段 B.并发进程中用于实现进程同步的程序段 C.并发进程中用户实现进程通信的程序段 D.并发进程中与共享变量有关的程序段 2.相关临界区是指( )。 A.一个独占资源 B.并发进程中与共享变量有关的程序段 c.一个共享资源 D.并发进程中涉及相同变量的那些程序段 3.管理若干进程共享某一资源的相关临界区应满足三个要求,其中( )不考虑。 A一个进程可以抢占己分配给另一进程的资源 B.任何进程不应该无限地逗留在它的临界区中c.一次最多让一个进程在临界区执行 D.不能强迫一个进程无限地等待进入它的临界区4、( )是只能由P和v操作所改变的整型变量。 A共享变量 B.锁 c整型信号量 D.记录型信号量 5.对于整型信号量,在执行一次P操作时,信号量的值应( )。 A.不变 B.加1 C减1 D.减指定数值 6.在执行v操作时,当信号量的值( )时,应释放一个等待该信号量的进程。 A>0 B.<0 c.>=0 D.<=0 7.Pv操作必须在屏蔽中断下执行,这种不可变中断的过程称为( )。 A初始化程序 B.原语 c.子程序 D控制模块 8.进程间的互斥与同步分别表示了各进程间的( )。 A.竞争与协作 B.相互独立与相互制约 c.不同状态 D.动态性与并发性 9并发进程在访问共享资源时的基本关系为( )。 A.相互独立与有交往的 B.互斥与同步 c并行执行与资源共享 D信息传递与信息缓冲 10.在进程通信中,( )常用信件交换信息。 A.低级通信 B.高级通信 c.消息通信 D.管道通信 11.在间接通信时,用send(N,M)原语发送信件,其中N表示( )。 A.发送信件的进程名 B.接收信件的进程名 C信箱名 D.信件内容 12.下列对线程的描述中,( )是错误的。 A不同的线程可执行相同的程序 B.线程是资源分配单位 c.线程是调度和执行单位 D.同一 进程中的线程可共享该进程的主存空间 13.实现进程互斥时,用( )对应,对同一个信号量调用Pv操作实现互斥。 A.一个信号量与一个临界区 B.一个信号量与—个相关临界区 c.一个信号量与一组相关临界 区 D一个信号量与一个消息 14.实现进程同步时,每一个消息与一个信号量对应,进程( )可把不同的消息发送出去。 A.在同一信号量上调用P操作 B在不同信号量上调用P操作 c.在同一信号量上调用v操作D.在不同信号量上调用v操作 (二)填空题 1.目前使用的计算机的基本特点是处理器______执行指令。 2.进程的______是指进程在顺序处理器上的执行是按顺序进行的。 3.当一个进程独占处理器顺序执行时,具有______和______两个特性。 4.进程的封闭性是指进程的执行结果只取决于______,不受外界影响。 5 进程的可再现性是指当进程再次重复执行时,必定获得______的结果。 6.一个进程的工作在没有全部完成之前,另一个进程就可以开始工作,则称这些进程为______.

进程同步实验报告

实验三进程的同步 一、实验目的 1、了解进程同步和互斥的概念及实现方法; 2、更深一步的了解fork()的系统调用方式。 二、实验内容 1、预习操作系统进程同步的概念及实现方法。 2、编写一段源程序,用系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。程序的输出是什么?分析原因。 3、阅读模拟火车站售票系统和实现进程的管道通信源代码,查阅有关进程创建、进程互斥、进程同步的系统功能调用或API,简要解释例程中用到的系统功能或API的用法,并编辑、编译、运行程序,记录程序的运行结果,尝试给出合理的解释。 4、(选做)修改问题2的代码,使得父子按顺序显示字符“a”;“b”、“c”编辑、编译、运行。记录程序运行结果。 三、设计思想 1、程序框架 (1)创建两个子进程:(2)售票系统:

(3)管道通信: 先创建子进程,然后对内容加锁,将输出语句存入缓存,并让子进程自己进入睡眠,等待别的进程将其唤醒,最后解锁;第二个子进程也执行这样的过程。父进程等待子进程后读内容并输出。 (4)修改程序(1):在子进程的输出语句前加上sleep()语句,即等待父进程执行完以后再输出。 2、用到的文件系统调用函数 (1)创建两个子进程:fork() (2)售票系统:DWORD WINAPI Fun1Proc(LPVOID lpPartameter); CreateThread(NULL,0,Fun1Proc,NULL,0,NULL); CloseHandle(hThread1); (HANDLE)CreateMutex(NULL,FALSE,NULL); Sleep(4000)(sleep调用进程进入睡眠状态(封锁), 直到被唤醒); WaitForSingleObject(hMutex,INFINITE); ReleaseMutex(hMutex); (3)管道通信:pipe(fd),fd: int fd[2],其中: fd[0] 、fd[1]文件描述符(读、写); lockf( fd,function,byte)(fd: 文件描述符;function: 1: 锁定 0:解锁;byte: 锁定的字节数,0: 从当前位置到文件尾); write(fd,buf,byte)、read(fd,buf,byte) (fd: 文件描述符;buf : 信息传送的源(目标)地址;byte: 传送的字节数); sleep(5); exit(0); read(fd[0],s,50) (4)修改程序(1):fork(); sleep(); 四、调试过程 1、测试数据设计 (1)创建两个子进程:

实验二 进程管理

实验二进程管理 实验目的 通过进程的创建、撤销和运行加深对进程概念和进程并发执行的理解,明确进程与程序的区别。 实验内容 1、了解系统调用fork()、exec()、exit()和waitpid()的功能和实现过程。 2、编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 3、编写一段程序,使用系统调用fork()来创建一个子进程,子进程通过系统调用exec()更换自己的执行代码,显示新的代码“new program.”后,调用exit()结束。而父进程则调用waitpid()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。

实验指导 一、所涉及的系统调用 1、getpid 在2.4.4版内核中,getpid是第20号系统调用,其在Linux函数库中的原型是: getpid的作用很简单,就是返回当前进程的进程ID,请大家看以下的例子: 这个程序的定义里并没有包含头文件sys/types.h,这是因为我们在程序中没有用到pid_t类型,pid_t类型即为进程ID的类型。事实上,在i386架构上(就是我们一般

PC计算机的架构),pid_t类型是和int类型完全兼容的,我们可以用处理整形数的方法去处理pid_t类型的数据,比如,用"%d"把它打印出来。 编译并运行程序getpid_test.c: 再运行一遍: 正如我们所见,尽管是同一个应用程序,每一次运行的时候,所分配的进程标识符都不相同。 2、fork 在2.4.4版内核中,fork是第2号系统调用,其在Linux函数库中的原型是:

操作系统-进程管理实验报告

实验一进程管理 1.实验目的: (1)加深对进程概念的理解,明确进程和程序的区别; (2)进一步认识并发执行的实质; (3)分析进程争用资源的现象,学习解决进程互斥的方法; (4)了解Linux系统中进程通信的基本原理。 2.实验预备内容 (1)阅读Linux的sched.h源码文件,加深对进程管理概念的理解; (2)阅读Linux的fork()源码文件,分析进程的创建过程。 3.实验内容 (1)进程的创建: 编写一段程序,使用系统调用fork() 创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 源代码如下: #include #include #include #include #include int main(int argc,char* argv[]) { pid_t pid1,pid2; pid1 = fork(); if(pid1<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid1 == 0){ printf("b\n"); } 1/11

else{ pid2 = fork(); if(pid2<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid2 == 0){ printf("c\n"); } else{ printf("a\n"); sleep(2); exit(0); } } return 0; } 结果如下: 分析原因: pid=fork(); 操作系统创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项。新进程和原有进程的可执行程序是同一个程序;上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互独立的进程!因此,这三个进程哪个先执行,哪个后执行,完全取决于操作系统的调度,没有固定的顺序。 (2)进程的控制 修改已经编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。 将父进程的输出改为father process completed 2/11

操作系统进程创建及通信实验报告

武汉工程大学计算机科学与工程学院 《操作系统》实验报告[Ⅰ]

一、实验目的 创建进程,实现进程消息通信和共享内存通信,了解进程的创建、退出和获取进程信。了解什么是映像文件、管道通信及其作用,掌握通过内存映像文件和管道技术实现进程通信。 二、实验内容 本例用三种方法实现进程通信,仅用于示例目的,没有进行功能优化。 1、创建进程A和B后,在进程A中输入一些字符,点“利用 SendMessage发送消息”按钮可将消息发到进程B。 2、在进程A中输入一些字符,点“写数据到内存映像文件”按钮, 然后在进程B中点“从内存映像文件读数据”按钮可收到消息。其中在点“写数据到内存映像文件”时,要求创建映像文件,B进程在印象文件中读取数据。 3、先在进程B中点“创建管道并接收数据”按钮,然后在进程A 中输入一些字符,点“写数据到管道文件”按钮可将消息发到进程B。管道是连接读/写进程使他们进行通信的一个共享文件,目的是更好地实现进程间的通信。 三、实验思想 这次试验最主要的内容和核心思想就是学会创建进程并实现进程间的简单通信、创建映像文件和创建管道文件来通信,后两者是实现进程通信的高级通信机制中的两种。. 创建一个程序A和程序B,其中程序A和B各有一个主窗体,A主窗体上要求可以实现创建进程B(即调用函数B)、结束进程B、关闭进程A、向进程B发送数据、创建映像文件、创建管道文件等功能,进程B要求有从映像文件读取数据、创建管道并接收数据、结束进程B功能。最终让A、B进程相互通信。

四、设计分析: 首先设得设计A、B两个程序的操作界面,然后编写各个功能模块。对于A 程序窗体,在“利用SendMessage发送消息”按钮的消息响应函数中,主要是利用Windows API函数CWnd::FindWindow来找到接收消息的窗体,即进程B,找到进程B后,利用这个函数返回的窗体指针的SendMessage函数来发送消息。在“写数据到内存印象文件”按钮的消息响应函数中,主要是利用函数CreateFileMapping来创建一个印象文件,这个函数返回的是这个印象文件的句柄,然后将这个句柄和要发送的消息字符串传递到函数sprintf中,就可以所要发送的消息写入印象文件,在B程序窗体中有个“从内存印象文件读数据”按钮,在这个按钮的消息响应函数中读取父进程所创建的印象文件中的数据就可以实现通信了。在B程序窗体按钮“写数据到管道文件”的消息响应函数中,不能直接将要发送的消息发送到管道文件,因为管道必须先由子进程通过函数CreateNamedPipe创建,只有待子进程创建好管道后父进程才能根据管道创建管道文件,将消息写入管道文件并及时发送给子进程。而且这个管道只能使用一次,即每次发送完消息后那个管道不能在使用了,必须再由子进程创建一个管道,A 进程才能再次创建管道文件并向其中写入消息。这个程序也不一定要MFC实现,还可以用其他的技术和语言实现,比如说Java、VB等,外表构架可以不一样,但核心技术都是一样的,只是不同的调用形式和调用方法,比如说在VB中,实现进程间的一般通信就是使用动态数据交换DDE,实现起来就比较简单,但是要创建映像文件和管道文件就比较繁琐,可以根据不同的需求采用不同的语言。 五、程序部分源代码: 1.“利用SendMessage发送消息”按钮中的主要代码 //找到接收消息的窗口(窗口名为Receiver) CString str="进程B"; CWnd *pWnd=CWnd::FindWindow(NULL,str); if(pWnd) { COPYDATASTRUCT buf; char * s=new char[m_Msg1.GetLength()]; //m_Msg1为CString类型的变量 s=m_Msg1.GetBuffer(0);

相关文档
最新文档