操作系统实验报告班级:030613学号:03061331姓名:裴帅帅实验一:进程的建立一、实验内容创建进程及子进程,在父子进程间实现进程通信,创建进程并显示标识等进程控制块的属性信息,显示父子进程的通信信息和相应的应答信息。
使用匿名管道实现父子进程之间的通信。
二、源程序1、创建匿名管道SECURITY_ATTRIBUTES sa;sa.bInheritHandle=true;sa.lpSecurityDescriptor=NULL;sa.nLength=sizeof(SECURITY_ATTRIBUTES);if(!CreatePipe(&m_hRead,&m_hWrite,&sa,0)){MessageBox("创建匿名管道失败");return false;}2、创建子进程STARTUPINFO si;ZeroMemory(&si,sizeof(STARTUPINFO));si.cb=sizeof(STARTUPINFO);si.dwFlags=STARTF_USESTDHANDLES;si.hStdInput=m_hRead;si.hStdOutput=m_hWrite;si.hStdError=GetStdHandle(STD_ERROR_HANDLE);if(!CreateProcess(NULL,"子进.exe",NULL,NULL,true,0,NULL,NULL,&si,&pi)) {MessageBox("创建子进程失败");CloseHandle(m_hRead);CloseHandle(m_hWrite);m_hRead=NULL;m_hWrite=NULL;return;}3、销毁子进程if(m_hRead)CloseHandle(m_hRead);if(m_hWrite)CloseHandle(m_hWrite);TerminateProcess(pi.hProcess ,0);4、向匿名管道中写信息即发送信息DWORD deWrite;CString sendData;m_s.GetWindowText(sendData);int length;length=sendData.GetLength ();char *buffer=new char[length+1];for(int i=0;i<length;i++){buffer[i]=sendData[i];}buffer[length]='\0';if(!WriteFile(m_hWrite,buffer,length,&deWrite,NULL)){MessageBox("发送数据失败");}delete buffer;5、从匿名管道中读取信息即接收信息char buff[100];DWORD deRead;if(!ReadFile(m_hRead,buff,100,&deRead,NULL)){MessageBox("读取数据失败");}CString receiveData;for(int i=0;i<=(int)deRead;i++){receiveData+=buff[i];}receiveData+='\0';m_r.SetWindowText (receiveData);三、实验结果实验结果实现了父进程向匿名管道中写信息,然后在子进程端可以从匿名管道中读取该信息;也可以子进程向管道中写入信息,然后父进程从中读取后显示。
以下是实验结果截图:1、父进程发送信息2、子进程接收信息四、总结分析本实验用匿名管道实现了父子之间的通信过程,通过本实验要掌握几个MFC 函数包括,创建管道、往管道中写入数据、从管道中读取数据、创建子进程、销毁子进程等。
实验二:进程间的同步一、实验内容实现进程同步和互斥模型,利用通信API实现进程之间的同步,建立司机和售票员进程,并实现他们间的同步运行。
使用事件作为相互竞争的进程的争抢资源,演示过程:司机开车,到站停车,售票员开车门,乘客上车,售票员关门,买票,司机继续开车。
本试验用两条线程演示进程间的相互关系。
二、源程序1、创建两条线程两个线程分别基于司机线程(函数)function1,售票员线程(函数)function2建立:unsigned long threadId1,threadId2;HANDLE thread1,thread2;thread1=CreateThread(NULL,0,function1,NULL,0,&threadId1);thread2=CreateThread(NULL,0,function2,NULL,0,&threadId2); CloseHandle(thread1);CloseHandle(thread2);2、创建两个事件作为两个线程各自的独占资源hMutex1=CreateEvent(NULL,false,false,NULL);hMutex2=CreateEvent(NULL,false,false,NULL);其中两个事件变量均为全局变量设定主线程休眠一定时间3、司机线程运行函数代码DWORD WINAPI function1( LPVOID lpParameter){while(true){cout<<"正常行车,到站、停车"<<endl;SetEvent(hMutex2);//V操作WaitForSingleObject(hMutex1,INFINITE);ResetEvent(hMutex1); //P操作cout<<"离站开车"<<endl;}return 0;}4、售票员线程运行函数代码DWORD WINAPI function2( LPVOID lpParameter){while(true){WaitForSingleObject(hMutex2,INFINITE);ResetEvent(hMutex2);cout<<"开车门,关车门"<<endl;cout<<"售票"<<endl;SetEvent(hMutex1);}return 0;}三、实验结果实验结果实现了司机、售票员工作的交叉进行,这些都是资源的相互占用、等待、释放所实现的实验结果截图:四、总结分析通过这次试验,学会了两个好技能:第一,在写程序的时候使用线程,使用线程可以让不同的工作并行进行,不容易混乱,卡死;第二,使用事件即event 实现信号量的作用,保证两个关联线程的运行相互联系和制约。
实验三:文件系统的设计与基本操作的实现一、实验内容选择一种操作系统,理解其文件系统结构,设计并实现文件系统的描述结构,本实验选用windows的文件系统,实现系统文件的显示。
二、源程序本实验源程序大致分两步:第一步,在初始化程序时,固定一个盘检索文件;第二部,选去另一个盘后,自动进行新卷的文件检索。
1、初始化应用程序时,设定磁盘,并且在树状控件中插入根节点CString path;path="E:";m_Root=path;HTREEITEM TreeItem=m_tree.InsertItem (m_Root,TVI_ROOT,TVI_SORT);m_ComBox.SetCurSel(2);m_Edit.SetWindowText(path);path+="\\*.*";DeleteListItem();//删除右侧列表框中的文件列表,以便更新2、获取路径和树中节点后,以当前节点进行文件查找void CFileDlg::FindFile(CString Path, HTREEITEM TreeItem){CString str;HANDLE hFind;WIN32_FIND_DATA fd;hFind=::FindFirstFile((LPCTSTR)Path,&fd);if(hFind!=INVALID_HANDLE_VALUE){do{if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)//目录,则显示在右侧树状图{str=(LPCTSTR)&fd.cFileName ;if( str!=_T(".") && str!=_T("..") ){m_tree.InsertItem (str,TreeItem,TVI_SORT);}}Else//非目录,及文件,则显示在右侧栏{str=(LPCTSTR)&fd.cFileName ;m_List.AddString (str);}}while(::FindNextFile (hFind,&fd));}else{m_tree.DeleteAllItems ();MessageBox("路径不对!","Error",MB_OK|MB_OKCANCEL|MB_ICONERROR);}FindClose(hFind);for(int i=0;i<20;i++)strName[i]="";//本数组用来存储文件路径m_iIndex=0;//用来标志strName数组中的节点位置}3、改变组合框中的盘符号时,对左侧的树状图进行更新int iIndex=m_ComBox.GetCurSel();CString str;m_ComBox.GetLBText (iIndex,str);if(str!=m_Root){DeleteListItem();//删除右侧栏目m_tree.DeleteAllItems ();//删除左侧树状图m_Root=str;m_Edit.SetWindowText (str);str+="\\*.*";HTREEITEM TreeItem=m_tree.InsertItem(m_Root,TVI_ROOT,TVI_SORT);//插入新的右侧树根节点FindFile(str,TreeItem);m_tree.Expand (TreeItem,TVE_EXPAND);}4、点击左侧树状图的节点时,查找其目录下的目录和文件CString str,node,Path;HTREEITEM ParentItem;HTREEITEM TreeItem=m_tree.GetSelectedItem ();ParentItem=TreeItem;str=m_tree.GetItemText (TreeItem);strName[m_iIndex++]=str;//点击一个节点后,先要获取本节点的id,然后用数据结构中查找树根节点的算法进行查找树根节点,所用方法为,设置两个指针,一个指向本id,另一个指向其父亲,然后其父亲的指针再指向其父亲,依次循环,最终知道指针指到了根节点结束本次搜索。