合肥工业大学操作系统实验报告(2)

2018-11-26 22:38

StartupInfo.StdInput = GetStdHandle(STD_INPUT_HANDLE); StartupInfo.StdOutput = GetStdHandle(STD_OUTPUT_HANDLE); StartupInfo.StdError = GetStdHandle(STD_ERROR_HANDLE); //

// 为一个应用程序同时创建两个子进程。 //

if (CreateProcess(\ && CreateProcess(\ //

// 创建子进程成功,等待子进程运行结束。 //

WaitForSingleObject(ProcInfoOne.ProcessHandle, INFINITE); WaitForSingleObject(ProcInfoTwo.ProcessHandle, INFINITE); //

// 得到并输出子进程的退出码。 // GetExitCodeProcess(ProcInfoOne.ProcessHandle, &ulExitCode); printf(\ GetExitCodeProcess(ProcInfoTwo.ProcessHandle, &ulExitCode); printf(\ // // 关闭不再使用的句柄。 // CloseHandle(ProcInfoOne.ProcessHandle); CloseHandle(ProcInfoOne.ThreadHandle); CloseHandle(ProcInfoTwo.ProcessHandle); CloseHandle(ProcInfoTwo.ThreadHandle); } else { printf(\ nResult = 1; } return nResult; }

作用: 在eosapp.exe父进程下,为hello.exe创建两个子进程,分别等待两个子进程结束,得到退出码后关闭句柄。

结果:交替分别显示两遍\以及” Bye-bye!”。

三、思考与练习

3.在 PsCreateProcess 函数中调用了 PspCreateProcessEnvironment 函数后又先后调用了PspLoadProcessImage 和 PspCreateThread 函数,学习这些函数的主要功能。能够交换这些函数被调用的顺序吗?思考其中的原因。

答: PspCreateProcessEnvironment的主要功能是创建进程控制块,并且为进程创建地址空间和分配句柄表。PspLoadProcessImage是将进程的可执行映像加载到进程的地址空间中。PspCreateThread创建了进程的主线程。这三个函数被调用的顺序是不能够改变的。加载可执行映像之前必须已经为进程分配了地址空间,这样才能够确定可执行映像可以被加载到内

存的位置;在创建主线程之前必须已经加载过可执行映像,这样主线程才知道指令分工以及开始执行的位置。因此不能交换他们的顺序。

四、备注说明

在机房完成。

实验5 进程的同步

一、实验目的

使用 EOS 的信号量,编程解决生产者—消费者问题,理解进程同步的意义。 调试跟踪 EOS 信号量的工作过程,理解进程同步的原理。

修改 EOS 的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。

二、实验过程记录

1.

/*pc.c*/

#include \//

// 缓冲池。 //

#define BUFFER_SIZE int Buffer[BUFFER_SIZE]; //

// 产品数量。 //

#define PRODUCT_COUNT //

10

30

// 用于生产者和消费者同步的对象句柄。 //

HANDLE MutexHandle;

HANDLE EmptySemaphoreHandle; HANDLE FullSemaphoreHandle; //

// 生产者和消费者的线程函数 //

ULONG Producer(PVOID Param); ULONG Consumer(PVOID Param); //

// main 函数参数的意义:

// argc - argv 数组的长度,大小至少为 1,argc - 1 为命令行参数的数量。

// argv - 字符串指针数组,数组长度为命令行参数个数 + 1。其中 argv[0] 固定指向当前 // 进程所执行的可执行文件的路径字符串,argv[1] 及其后面的指针指向各个命令行

// 参数。

// 例如通过命令行内容 \启动进程后,hello.exe 的 main 函 // 数的参数 argc 的值为 3,argv[0] 指向字符串 \,argv[1] 指向 // 参数字符串 \,argv[2] 指向参数字符串 \。 //

int main(int argc, char* argv[]) { HANDLE ProducerHandle; HANDLE ConsumerHandle; #ifdef _DEBUG __asm(\#endif // // 创建用于互斥访问缓冲池的 Mutex 对象。 // MutexHandle = CreateMutex(FALSE, NULL); if (NULL == MutexHandle) { return 1; } // // 创建 Empty 信号量,表示缓冲池中空缓冲区数量。初始计数和最大计数都为 BUFFER_SIZE。 // EmptySemaphoreHandle = CreateSemaphore(BUFFER_SIZE, BUFFER_SIZE, NULL); if (NULL == EmptySemaphoreHandle) { return 2; } // // 创建 Full 信号量,表示缓冲池中满缓冲区数量。初始计数为 0,最大计数为 BUFFER_SIZE。 // FullSemaphoreHandle = CreateSemaphore(0, BUFFER_SIZE, NULL); if (NULL == FullSemaphoreHandle) { return 3; } //

// 创建生产者线程。 //

ProducerHandle = CreateThread( 0, Producer, NULL, 0, NULL ); if (NULL == ProducerHandle) { return 4;

// 默认堆栈大小

// 线程函数入口地址 // 线程函数参数 // 创建标志 // 线程 ID

} //

// 创建消费者线程。 //

ConsumerHandle = CreateThread( 0, Consumer, NULL, 0, NULL ); if (NULL == ConsumerHandle) { return 5; } //

// 等待生产者线程和消费者线程结束。 // WaitForSingleObject(ProducerHandle, INFINITE); WaitForSingleObject(ConsumerHandle, INFINITE); // // 关闭句柄 // CloseHandle(MutexHandle); CloseHandle(EmptySemaphoreHandle); CloseHandle(FullSemaphoreHandle); CloseHandle(ProducerHandle); CloseHandle(ConsumerHandle); return 0; } //

// 生产者线程函数。 //

ULONG Producer(PVOID Param) { int i; int InIndex = 0; for (i = 0; i < PRODUCT_COUNT; i++) { WaitForSingleObject(EmptySemaphoreHandle, INFINITE); WaitForSingleObject(MutexHandle, INFINITE); printf(\ Buffer[InIndex] = i; InIndex = (InIndex + 1) % BUFFER_SIZE; ReleaseMutex(MutexHandle); ReleaseSemaphore(FullSemaphoreHandle, 1, NULL); // // 休息一会。每 500 毫秒生产一个数。

// Sleep(500); } return 0; } //

// 消费者线程函数。 //

ULONG Consumer(PVOID Param) { int i; int OutIndex = 0; for (i = 0; i < PRODUCT_COUNT; i++) { WaitForSingleObject(FullSemaphoreHandle, INFINITE); WaitForSingleObject(MutexHandle, INFINITE); printf(\ OutIndex = (OutIndex + 1) % BUFFER_SIZE; ReleaseMutex(MutexHandle); ReleaseSemaphore(EmptySemaphoreHandle, 1, NULL); // }

// 休息一会儿。让前 10 个数的消费速度比较慢,后面的较快。 // if (i < 10) { Sleep(2000); } else { Sleep(100); } }

return 0;

作用:演示生产者、消费者问题。创建Mutex对象->创建Empty信号量对象->创建Full信号量对象->创建生产者线程->创建消费者线程->等待生产者线程和消费者线程结束->关闭句柄 结果:


合肥工业大学操作系统实验报告(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:论军事信息技术与现代战争

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: