文档视界 最新最全的文档下载
当前位置:文档视界 › 操作系统实验教案(打印版)

操作系统实验教案(打印版)

操作系统实验教案(打印版)
操作系统实验教案(打印版)

《操作系统原理》

实验教案(基于Windows2000/XP平台)

讲授人:徐旭

安排授课时间:2012-2013(二)

授课对象:12计科专升本

实验项目列表

实验一多线程的创建与撤销

实验二线程的同步

实验三线程的互斥

实验四生产者-消费者问题

实验五进程通信

实验六动态链接库的建立和调试

实验七页面置换算法模拟

实验八文件的三种传输模式及性能比较实验九磁盘的读写

附录部分(可扩充)

附录1 读者-写者问题

附录2 梨子苹果之PV操作

附录3 命名管道编程规范

附录4 DLL编程规范

实验一线程的创建与撤销

一、实验目的

通过本实验熟悉Windows系统提供的线程创建与撤销等API系统调用,掌握Windows 系统环境下线程的创建与撤销方法。

二、实验内容

1. 熟悉开发环境Visual C++ 6.0;

2. Windows系统环境下线程的创建与撤销方法;

3.编程:在主线程中调用CreateThread( )创建1个子线程,并在子线程中显示类似“Thread is running !”等字样。

三、实验准备知识

相关的API函数的函数原型:

1. 线程创建函数HANDLE CreateThread();

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes DWORD dwStackSize, // initial thread stack size LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function

LPVOID lpParameter, // argument for new thread

DWORD dwCreationFlags, // creation flags

LPDWORD lpThreadId// pointer to receive thread ID

);

线程函数原型DWORD WINAPI Thread1Proc(LPVOID lpParameter)

2. 线程撤销函数

VOID ExitThread(

DWORD dwExitCode// exit code for this thread

);

功能:撤销一个线程。该函数将终止线程的运行,并导致操作系统清除该线程使用的所有操作系统资源。但是,C + +资源(如C + +类对象)将不被撤消。

说明:如果在主线程函数(main函数)中调用ExitThread,那么应用程序的主线程将停止运行。但是,如果进程中至少有一个线程还在运行,该进程将不会终止运行。

3. 线程终止函数TerminateThread();

4. 线程挂起函数Sleep();进程主动放弃剩余的时间片。

5. 关闭句柄函数CloseHandle( )。

说明:关闭一个对象句柄,只是将相应对象的引用数减一,并不意味着终结该对象,除非引用数减至零。

四、程序源代码及注释

【主要源代码参考】

#include

#include

第一条语句:void threadName1();

static HANDLE hThread1=NULL;//存放创建的子进程的句柄

DWORD dwThreadID1; //存放创建的子进程的ID

DWORD WINAPI Thread1Proc( LPVOID ); //子线程函数的声明

int main() // 主线程

{//创建子线程

Int nRetcode=0;

hThread1 = CreateThread(NULL,0, Thread1Proc, NULL,0,threadName1,

NULL, 0,& dwThreadID1); //创建子线程Sleep(5000);//挂起时间

Printf(“你好!”);//后执行本条语句

CloseHandle(hThread1); // 关闭句柄

ExitThread(0); // 撤销本线程

//return 0;

return nRetcode;

}

Void threadName1()

{

Printf(“Thread is running!\n”);//先执行本条语句

}

//子线程的实现

DWORD WINAPI Thread1Proc(LPVOID lpParameter )

{

cout<<"Thread is running!"<

return 0;

}

五、实验结果输出

排版说明(小三、小四、五号)

实验二线程的同步

一、实验任务

该实验完成Windows中多线程同步运行的验证。首先在主线程中创建一个子线程,成功创建后进入阻塞状态,直到子线程运行完毕后唤醒主线程。

二、实验目的

1.进一步掌握Windows系统环境下线程的创建与撤消。

2.熟悉Windows系统提供的线程同步API。

3.使用Windows系统提供的线程同步API解决实际问题。

三、实验准备知识

1.Wait函数

等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为受信(signaled)状态或超时为止。

函数原型:

DWORD WaitForSingleObject(

HANDLE hHandle, // handle to object to wait for

DWORD dwMilliseconds // time-out interval in milliseconds );

功能:在指定的时间内等待一个对象。

举例:WaitForSingleObject(hThread,1000);//等待一个线程终止,等待1000毫秒WaitForSingleObject(hMutex,INFINITE); //无限等待一个互斥对象,//直到变成“可信”

DWORD WaitForMultipleObjects(

DWORD nCount, // number of handles in the handle array

CONST HANDLE *lpHandles, // pointer to the object-handle array

BOOL fWaitAll, // wait flag

DWORD dwMilliseconds // time-out interval in milliseconds

);

功能:在指定时间内等待多个对象。

举例:HANDLE h [3];

h[0]=hThread1;

h[1]=hThread2;

h[2]=hThread3;

DWORD dw=WaitForMultipleObject(3,h,true,-1);

2.信号量对象(Semaphore)

信号量对象用于对资源进行计数,它的使用规则如下:

?如果当前资源的数量大于0,则处于“受信”状态。

?如果当前资源数量是0,则“未受信”状态。所有等待此信号量的线程均进入等待状

态(或称不可调度状态)。

函数原型:

HANDLE CreateSemaphore(

LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

// pointer to security attributes

LONG lInitialCount, // initial count

LONG lMaximumCount, // maximum count

LPCTSTR lpName // pointer to semaphore-object name

);

功能:创建一个信号量。

举例:

hHandle1=CreateSemaphore(NULL,0,5,”Semaphore1”);

HANDLE OpenSemaphore(

DWORD dwDesiredAccess, // access flag

BOOL bInheritHandle, // inherit flag

LPCTSTR lpName // pointer to semaphore-object name

);

功能:打开一个已存在的信号量。

举例:

hHandle2=OpenSemaphore(SEMAPHORE_MODIFY_STATE| SYNCHRONIZE,NULL,"SemaphoreName1");

BOOL ReleaseSemaphore(

HANDLE hSemaphore, // handle to the semaphore object

LONG lReleaseCount, // amount to add to current count

LPLONG lpPreviousCount // address of previous count

);

功能:对指定的信号量对象增值。

举例:

rc= ReleaseSemaphore(hHandle1,1,NULL);

四、程序源代码及注释

【主要源代码参考】

//定义全局变量,诸线程均可访问

static HANDLE hThread1; //子进程的句柄,作为主线程的局部变量也行

static HANDLE hHandle1=NULL; //信号量的句柄,全局变量

void func(); //子线程的声明

int _tmain(int argc,TCHAR* argv[],TCHAR* envp[])

{

int nRetCode=0;

DWORD dwThreadID1;

DWORD dRes,err;

hHandle1=CreateSemaphore(NULL,0,1,"SemaphoreName1"); //创建一个信号量

if(hHandle1==NULL) printf("Semaphore Create Fail!\n");

else printf("Semaphore Create Success!\n");

hHandle1=OpenSemaphore(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE,NULL,"S emaphoreName1");

if(hHandle1==NULL)printf("Semaphore Open Fail!\n");

else printf("Semaphore Open Success!\n");

hThread1=CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0,

(LPTHREAD_START_ROUTINE)func,

(LPVOID)NULL,

0,&dwThreadID1); //创建子线程

if (hThread1==NULL) printf("Thread1 create Fail!\n");

else printf("Thread1 create Success!\n");

dRes=WaitForSingleObject(hHandle1,INFINITE); //主线程等待子线程结束err=GetLastError();

printf("WaitForSingleObject err=%d\n",err);

if(dRes==WAIT_TIMEOUT)

printf("TIMEOUT!dRes=%d\n",dRes);

else if(dRes==WAIT_OBJECT_0)

printf("WAIT_OBJECT!dRes=%d\n",dRes);

else if(dRes==WAIT_ABANDONED)

printf("WAIT_ABANDONED!dRes=%d\n",dRes);

else printf("dRes=%d\n",dRes);

CloseHandle(hThread1);

CloseHandle(hHandle1);

ExitThread(0);

return nRetCode;

}

//实现子线程

void func()

{

BOOL rc;

DWORD err;

printf("Now In Thread !\n");

rc=ReleaseSemaphore(hHandle1,1,NULL); //子线程唤醒主线程

err=GetLastError();

printf("ReleaseSemaphore err=%d\n",err);

if(rc==0) printf("Semaphore Release Fail!\n");

else printf("Semaphore Release Success!rc=%d\n",rc);

}

五、实验结果输出

实验三线程的互斥

一、实验任务

完成两个子线程之间的互斥。在主线程中使用系统调用CreateThread()创建两个子线程,并使两个子线程互斥的使用全局变量count。

二、实验目的

1.熟练掌握Windows系统环境下线程的创建与撤销。

2.熟悉Windows系统提供的线程互斥API。

3.使用Windows系统提供的线程互斥API解决实际问题。

三、实验准备知识

1.使用临界区对象(Criticalsection)

Critical Section Object ,A segment of code that is not reentrant and therefore does not support concurrent access by multiple threads. Often, a critical section object is used to protect shared resources。通过定义在数据段中的一个CRITICAL_SECTION 结构实现。

CRITICAL_SECTION myCritical;

并且在任何线程使用此临界区对象之前必须对它进行初始化。

void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection );

之后,任何线程访问临界区中数据的时候,必须首先调用EnterCriticalSection 函数,申请进入临界区(又叫关键代码段,使用共享资源的任何代码都必须封装在此)。在同一时间内,Windows 只允许一个线程进入临界区。所以在申请的时候,如果有另一个线程在临界区的话,EnterCriticalSection 函数会一直等待下去,直到其他线程离开临界区才返回。EnterCriticalSection 函数用法如下:

void EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection);

当操作完成的时候,还要将临界区交还给Windows,以便其他线程可以申请使用。这个工作由LeaveCriticalSection 函数来完成。

void LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection);

当程序不再使用临界区对象的时候,必须使用DeleteCriticalSection 函数将它删除。

void DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection);

2.使用互斥锁(Interlocked)

提供一种手段来保证值的递增(减)能够以原子操作方式来进行,也就是不中断地进行。

LONG InterlockedIncrement( LPLONG lpAddend ) ; // 增一操作

LONG InterlockedDecrement( LPLONG lpAddend); // 减一操作

LONG InterlockedExchangeAdd (

PLONG Addend, // pointer to the addend

LONG Increment // increment value

); //增减任意值

四、程序源代码及注释

【主要源代码参考】这里以使用临界区对象为例

static int count=5; //共享变量

static HANDLE h1,h2; //两个子进程的句柄变量

LPCRITICAL_SECTION hCriticalSection; //定义指向临界区对象的地址指针

CRITICAL_SECTION Critical; //定义临界区

void func1( ) //线程函数的定义不符合WIN32格式,后面CreateThread函数中void func2( ) //要附加强制类型转换

//主线程的实现

int _tmain(int argc, TCHAR* argv[],TCHAR* envp[])

{

int nRetCode=0;

DWORD dwThreadID1, dwThreadID2;

hCriticalSection=&Critical; //将指向临界区的对象的指针指向临界区

InitializeCriticalSection(hCriticalSection); //初始化临界区

//创建子线程func1

h1=CreateThread((LPSECURITY_ATTRIBUTES)NULL,

0,

(LPTHREAD_START_ROUTINE)func1,

(LPVOID)NULL,

0,&dwThreadID1);

if(h1==NULL)printf("Thread1 create Fail!\n");

else printf("Thread1 create success!\n");

//创建子线程func2

h2=CreateThread((LPSECURITY_ATTRIBUTES)NULL,

0,

(LPTHREAD_START_ROUTINE)func2,

(LPVOID)NULL,

0,&dwThreadID2);

if(h2==NULL) printf("Thread2 create Fail!\n");

else printf("Thread2 create success!\n");

Sleep(1000);

CloseHandle(h1);

CloseHandle(h2);

DeleteCriticalSection(hCriticalSection); //删除临界区

ExitThread(0);

return nRetCode;

}//主线程结束

//子线程fun c2的实现

void func2()

{

int r2;

EnterCriticalSection(hCriticalSection); //进入临界区

r2=count;

Sleep(100);

r2=r2+1;

count=r2;

printf("count in func2=%d\n",count);

LeaveCriticalSection(hCriticalSection); //退出临界区}

//子线程func1的实现

void func1()

{

int r1;

EnterCriticalSection(hCriticalSection); //进入临界区

r1=count;

Sleep(500);

r1=r1+1;

count=r1;

printf("count in func1=%d\n",count);

LeaveCriticalSection(hCriticalSection); //退出临界区

}

五、实验结果输出参考

实验四生产者消费者问题

一、实验任务

1.在WINDOWS 2000环境下,创建一个控制台进程,此进程包括多个生产者线程和多个消费者线程。

2.用信号量机制解决进程(线程)的同步与互斥问题。

二、实验目的

1.掌握基本的同步互斥算法,理解生产者和消费者模型。

2.了解Windows 2000/XP中多线程的并发执行机制,线程间的同步和互斥。

3.学习使用Windows 2000/XP中基本的同步对象,掌握相应的API函数。

三、实验要求

1.生产者消费者对缓冲区进行互斥操作。

2.缓冲区大小为10,缓冲区满则不允许生产者生产数据,缓冲区空则不允许消费者消费数据。

3.生产者消费者循环操作可随时终止。

四、实验准备知识

1.互斥量对象(mutex)

互斥对象能够确保线程拥有对单个资源的互斥访问权。互斥对象包含一个引用数量,一个线程I D和一个递归计数器。

互斥对象的使用规则如下:

? 如果线程I D是0(这是个无效I D),互斥对象不被任何线程所拥有,互斥对象处于“受信”状态。

? 如果I D是个非0数字,那么一个线程就拥有互斥对象,互斥对象处于“未受信”状态。

函数原型

HANDLE CreateMutex(

LPSECURITY_ATTRIBUTES lpMutexAttributes,

// pointer to security attributes

BOOL bInitialOwner, // flag for initial ownership

LPCTSTR lpName // pointer to mutex-object name

);

作用:创建一个命名或无名互斥对象。

举例:

hHandle= CreateMutex(NULL,false,NULL);

//创建一个无名互斥对象,放弃拥有权(ownership),此时互斥量处于“受信”状态。HANDLE OpenMutex(

DWORD dwDesiredAccess, // access flag

BOOL bInheritHandle, // inherit flag

LPCTSTR lpName // pointer to mutex-object name

);

作用:打开一个命名的互斥对象。

BOOL ReleaseMutex(

HANDLE hMutex // handle to mutex object

);

作用:释放一个互斥对象,该函数同时将对象的递归计数器递减1。当递归计数器到达0时,该线程I D也被置为0,同时该对象变为“受信”状态。

说明:不同于其他内核对象,互斥对象有一个“线程所有权”的概念。当一个线程调用ReleaseMutex函数释放互斥对象时,该函数要查看调用线程的I D是否与互斥对象中的线程I D相匹配。如果两个I D相匹配,递归计数器就会递减;如果两个线程的I D不匹配,那么ReleaseMutex函数将不进行任何操作,而是将FALSE(表示失败)返回给调用者。

2.事件对象

事件对象能够通知一个操作已经完成。在所有的内核对象中,事件内核对象是个最基本的对象。它们包含一个使用计数,一个用于指明该事件是个自动重置的事件还是一个人工重置的事件的布尔值,另一个用于指明该事件处于“受信”状态还是“未受信”状态的布尔值。

函数原型

HANDLE CreateEvent(

LPSECURITY_ATTRIBUTES lpEventAttributes,

// pointer to security attributes

BOOL bManualReset, // flag for manual-reset event

BOOL bInitialState, // flag for initial state

LPCTSTR lpName // pointer to event-object name

);

作用:创建一个事件对象。

说明:有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。HANDLE OpenEvent(

DWORD dwDesiredAccess, // access flag

BOOL bInheritHandle, // inherit flag

LPCTSTR lpName // pointer to event-object name

);

作用:打开一个事件对象。

BOOL SetEvent(

HANDLE hEvent // handle to event object

);

作用:将事件对象设置为“受信”状态。

说明:当人工重置的事件为“受信”时,等待该事件的所有线程均变为可调度线程;当一个自动重置的事件为“受信”时,等待该事件的线程中只有一个线程变为可调度线程。

BOOL ResetEvent(

HANDLE hEvent // handle to event object

);

作用:将事件对象设置为“未受信”状态。

说明:Microsoft为自动重置的事件定义了应该成功等待的副作用规则,即当线程成功地等待到该对象时,自动重置的事件就会自动重置到“未受信”状态。通常没有必要为自动重置的事件调用ResetEvent函数,因为系统会自动对事件进行重置。但是,Microsoft没有为人工重置的事件定义成功等待的副作用,即线程必须使用ResetEvent才能使得重置到“未受信”状态。

五、程序源代码及注释

【主要源代码参考】

#include

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// The one and only application object

CWinApp theApp;

using namespace std;

const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度

unsigned short ProductID = 0; //这里的产品号和将被消耗的产品号是

unsigned short ConsumeID = 0; //为了跟踪产品的存取过程而引入的辅助变量

unsigned short in = 0; //缓冲区下标,指向生产者要放产品的缓冲区单元

unsigned short out = 0; //缓冲区下标,指向消费者要取产品的缓冲区单元

int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列

bool g_continue = true; //总控开关,可随时结束诸进程

HANDLE g_hMutex; //互斥信号量句柄,用于诸线程互斥访问缓冲区

HANDLE g_hFullSemaphore; //资源信号量句柄,代表缓冲区内已放置的产品数HANDLE g_hEmptySemaphore; //资源信号量句柄,代表缓冲区内空闲的单元数DWORD WINAPI Producer(LPVOID); //生产者线程声明

DWORD WINAPI Consumer(LPVOID); //消费者线程声明

int _tmain(int argc, TCHAR* argv[],TCHAR* envp[])

{ int nRetCode=0;

g_hMutex = CreateMutex(NULL,FALSE,NULL); //互斥信号量

g_hFullSemaphore = CreateSemaphore(

NULL,

0, //初始缓冲区内无产品

SIZE_OF_BUFFER-1,NULL);

g_hEmptySemaphore =CreateSemaphore(

NULL,

SIZE_OF_BUFFER-1, // 初始均是空缓冲区

SIZE_OF_BUFFER-1,NULL);

//调整下面的数值,可以发现,当生产者个数多于消费者个数时,

//生产速度快,生产者经常等待消费者;反之,消费者经常等待

const unsigned short PRODUCERS_COUNT = 3; //生产者的个数

const unsigned short CONSUMERS_COUNT = 1; //消费者的个数

const unsigned short THREADS_COUNT =

PRODUCERS_COUNT+CONSUMERS_COUNT; //总的线程数

HANDLE hThreads[THREADS_COUNT]; //诸线程的handle表DWORD producerID[CONSUMERS_COUNT]; //生产者线程的标识符表DWORD consumerID[PRODUCERS_COUNT]; //消费者线程的标识符表//创建生产者诸线程

for (int i=0;i

{

hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);

if (hThreads[i]==NULL) return -1;

}

//创建消费者线程

for (i=0;i

{

hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,

0,

Consumer,

NULL,

0,&consumerID[i]);

if (hThreads[i]==NULL) return -1;

}

while(g_continue)

{

if(getchar()) //按回车后终止程序运行

{

g_continue = false;

}

}

CloseHandle(g_hMutex);

CloseHandle(g_hEmptySemaphore);

CloseHandle(g_hFullSemaphore);

for(i=0;i

CloseHandle(hThreads[i]);

return nRetCode;

}//主线程main结束

//生产一个产品。简单模拟了一下,仅输出新产品的ID号

void Produce()

{

cerr << "Producing " << ++ProductID << " ... ";

cerr << "Succeed" <

}

//把新生产的产品放入缓冲区

void Append()

{

cerr << "Appending a product ... ";

g_buffer[in] = ProductID;

in = (in+1)%SIZE_OF_BUFFER;

cerr << "Succeed" <

//扫描缓冲区,输出缓冲区的当前状态

for (int i=0;i

{

cout << i <<": " << g_buffer[i];

if (i==in) cout << " <-- 生产";

if (i==out) cout << " <-- 消费";

cout <

}

}

//从缓冲区中取出一个产品

void Take()

{

cerr << "Taking a product ... ";

ConsumeID = g_buffer[out];

g_buffer[out] = -1;//取走产品后,设置为-1以示区别

out = (out+1)%SIZE_OF_BUFFER;

cerr << "Succeed" << endl;

//扫描缓冲区,输出缓冲区的当前状态

for (int i=0;i

{

cout << i <<": " << g_buffer[i];

if (i==in) cout << " <-- 生产";

if (i==out) cout << " <-- 消费";

cout << endl;

}

}

//消耗一个产品

void Consume()

{

cerr << "Consuming " << ConsumeID << " ... ";

cerr << "Succeed" <

}

//生产者线程的实现

DWORD WINAPI Producer(LPVOID lpPara)

{

while(g_continue)

{

WaitForSingleObject(g_hEmptySemaphore,INFINITE);

WaitForSingleObject(g_hMutex,INFINITE);

Produce();

Append();

Sleep(1500);

ReleaseMutex(g_hMutex);

ReleaseSemaphore(g_hFullSemaphore,1,NULL);

}

return 0;

}

//消费者进程的实现

DWORD WINAPI Consumer(LPVOID lpPara)

{

while(g_continue)

{

WaitForSingleObject(g_hFullSemaphore,INFINITE);

WaitForSingleObject(g_hMutex,INFINITE);

Take();

Consume();

Sleep(1500);

ReleaseMutex(g_hMutex);

ReleaseSemaphore(g_hEmptySemaphore,1,NULL);

}

return 0;

}

六、实验结果输出参考

实验五使用命名管道实现进程通信

一、实验任务

使用命名管道完成两个进程之间的通信。

二、实验目的

1.了解Windows系统环境下的进程通信机制;

2.熟悉Windows系统提供的进程通信用API。

三、实验准备知识

1.管道对象

“命名管道”或“命名管线”(Named Pipes)是一种简单的进程间通信(I P C)机制。命名管道可在同一台计算

机的不同进程之间,

或在跨越一个网络

的不同计算机的不

同进程之间,支持可

靠的、单向或双向的

数据通信。用命名管

道来设计应用程序

实际非常简单,并不

需要事先深入掌握基层网络传送协议(如T C P / I P或I P X)的知识。这是由于命名管道利用了微软网络提供者(M S N P)重定向器,通过一个网络,在各进程间建立通信。这样一来,应用程序便不必关心网络协议的细节。之所以要用命名管道作为自己的网络通信方案,一项重要的原因是它们充分利用了Windows NT及Windows 2000内建的安全特性。

命名管道的实施细节命令管道是围绕Windows文件系统设计的一种机制,采用“命名管道文件系统”(Named Pipe File System, NPFS)接口。因此,客户机和服务器应用可利用标准的Win32文件系统A P I函数(如ReadFile和WriteFile)来进行数据的收发。

创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。命名管道(Named Pipes)是在管道服务器和一台或多台管道客户机之间进行单向或双向通信的一种命名的管道。服务器是唯一一个有权创建命名管道的进程,也只有它才能接受管道客户机的连接请求。而客户机只能同一个现成的命名管道服务器建立连接。

命名管道的使用规则如下:

在服务器端第一次创建命名管道后等待连接,当客户端连接成功后,服务器端的命名管道就用作通讯用途。如果需要再次等待连接,服务器端就需要再次打开命名管道(创建一个命名管道的实例)并等待连接。

对于客户端,每次打开命名管道后建立与服务器间的连接,然后就可以利用命名管道进行通信,如果需要建立第二个连接则需要再次打开管道和再次建立连接。

2.相关的API函数

函数原型

HANDLE CreateNamedPipe(

LPCTSTR lpName, // pointer to pipe name

DWORD dwOpenMode, // pipe open mode

DWORD dwPipeMode, // pipe-specific modes

DWORD nMaxInstances, // maximum number of instances

DWORD nOutBufferSize, // output buffer size, in bytes

DWORD nInBufferSize, // input buffer size, in bytes

DWORD nDefaultTimeOut, // time-out time, in milliseconds

LPSECURITY_ATTRIBUTES lpSecurityAttributes // pointer to security attributes );

功能:创建一个命名管道实例。

说明:管道命名格式:\\服务器主机名或IP地址或.\pipe\管道名

举例:

BOOL ConnectNamedPipe(

HANDLE hNamedPipe, // handle to named pipe to connect LPOVERLAPPED lpOverlapped // pointer to overlapped structure

);

功能:管道服务器用来连接命名管道,类似于网络服务器的Listen;

BOOL DisconnectNamedPipe(

HANDLE hNamedPipe // handle to named pipe

);

功能:拆除与客户端的命名管道的连接;

BOOL CallNamedPipe(

LPCTSTR lpNamedPipeName, // pointer to pipe name

LPVOID lpInBuffer, // pointer to write buffer

DWORD nInBufferSize, // size, in bytes, of write buffer

LPVOID lpOutBuffer, // pointer to read buffer

DWORD nOutBufferSize, // size, in bytes, of read buffer

LPDWORD lpBytesRead, // pointer to number of bytes read

DWORD nTimeOut // time-out value, in milliseconds

);

功能:客户端与服务器端已建立的命名管道建立连接;

BOOL WaitNamedPipe(

LPCTSTR lpNamedPipeName, // pointer to name of pipe for which to wait DWORD nTimeOut // time-out interval, in milliseconds

);

功能:客户端等待服务器端命名管道。

四、程序源代码及注释

【主要源代码参考】

/*************服务器进程***********/

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

int nRetCode=0;

BOOL rc;

int err;

HANDLE hPipeHandle;

char lpName[]="\\\\.\\pipe\\myPipe";

char InBuffer[50]="";

char OutBuffer[50]="";

DWORD BytesRead,BytesWrite;

hPipeHandle=CreateNamedPipe(

(LPCTSTR)lpName,

PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED|WRITE_DAC,

PIPE_TYPE_MESSAGE|PIPE_READMODE_BYTE|PIPE_WAIT,

1,20,30,NMPWAIT_USE_DEFAULT_WAIT,

(LPSECURITY_ATTRIBUTES)NULL

) ; //创建命令管道

if((hPipeHandle==INVALID_HANDLE_VALUE)||(hPipeHandle==NULL))

{

err= GetLastError();

printf("Server Pipe Create Fail!err=%d\n",err);

exit(1);

}

else printf("Server Pipe Create Success!\n");

while(1) //连接命名管道

{

rc=ConnectNamedPipe(hPipeHandle,(LPOVERLAPPED)NULL);

if(rc==0)

{

err=GetLastError();

printf("Server Pipe Connect Fail!err=%d\n",err);

exit(2);

}

else printf("Server Pipe Connect Success!\n");

strcpy(InBuffer,"");

strcpy(OutBuffer,"");

//命名管道读数据

rc= ReadFile(hPipeHandle,InBuffer,sizeof(InBuffer),

&BytesRead,(LPOVERLAPPED)NULL);

if(rc==0 && BytesRead==0)

{

err=GetLastError();

printf("Server Pipe Read Fail!err=%d\n",err);

exit(3);

}

else printf("Server Pipe Read Success!\n DATA from Client is=%s\n",InBuffer);

rc=strcmp(InBuffer,"end");

if(rc==0) break;

printf("Please Input Data to Send\n");

scanf("%s",OutBuffer);

//向命令管道写数据

rc=WriteFile(hPipeHandle,OutBuffer,sizeof(OutBuffer),

&BytesWrite,(LPOVERLAPPED)NULL);

if(rc==0 )

{err=GetLastError();

printf("Server Pipe Write Fail!err=%d\n",err);}

else printf("Server Pipe Write Success!\n");

DisconnectNamedPipe(hPipeHandle); //拆除与管道命令连接

rc=strcmp(OutBuffer,"end");

if(rc==0) break;

}

printf("Now server be END!\n");

CloseHandle(hPipeHandle);

return nRetCode;

}

/***********客户端进程***********/

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])

{

BOOL rc=0;

char lpName[]="\\\\.\\pipe\\myPipe";

char InBuffer[50]="";

char OutBuffer[50]="";

DWORD BytesRead;

int nRetCode = 0;

int err=0;

while(1)

{

strcpy(InBuffer,"");

strcpy(OutBuffer,"");

printf("Input Data Please!\n");

scanf("%s",InBuffer);

if(!strcmp(InBuffer,"end"))

{CallNamedPipe(lpName,InBuffer,sizeof(InBuffer),OutBuffer,sizeof(OutBuffer), &BytesRead,NMPWAIT_USE_DEFAULT_WAIT);

break;}

rc=WaitNamedPipe(lpName,NMPWAIT_WAIT_FOREVER); //等待命名管道

if(rc==0)

{

err=GetLastError();

printf("Wait Pipe Fali!err=%d\n",err);

exit(1);

}

else printf("Wait Pipe Success!\n");

//使用管道命令读数据

rc=CallNamedPipe(lpName,InBuffer,sizeof(InBuffer),OutBuffer,sizeof(OutBuffer),

&BytesRead,NMPWAIT_USE_DEFAULT_WAIT);

rc=strcmp(OutBuffer,"end");

if (rc==0) break;

if (rc==0)

{

err=GetLastError();

printf("Call Pipe Fali!err=%d\n",err);

exit(1);

}

else printf("Call Pipe Success!\n Data from Server is %s\n",OutBuffer);

}

printf("Now Client to be END!\n");

return nRetCode;

}

五、实验结果输出参考

操作系统上机实验报告(西电)

操作系统上机题目 一、题目 实验1:LINUX/UNIX Shell部分 (一)系统基本命令 1.登陆系统,输入whoami 和pwd ,确定自己的登录名和当前目录; 登录名yuanye ,当前目录/home/yuanye 2.显示自己的注册目录?命令在哪里? a.键入echo $HOME,确认自己的主目录;主目录为/home/yuanye b.键入echo $PA TH,记下自己看到的目录表;/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games c.键入which abcd,看看得到的错误信息; 再键入which ls 和which vi,对比刚刚得到的结果的目录是否在a.、b. 两题看到的目录表中; /bin/ls /usr/bin/vi 3.ls 和cd 的使用: a.键入ls,ls -l ,ls -a ,ls -al 四条命令,观察输出,说明四种不同使用方式的区别。 1. examples.desktop 公共的模板视频图片文档音乐桌面; 总计32 2.-rw-r--r-- 1 yuanye yuanye 357 2011-03-22 22:15 examples.desktop drwxr-xr-x 2 yuanye yuanye 4096 2011-03-22 23:25 公共的 drwxr-xr-x 2 yuanye yuanye 4096 2011-03-22 23:25 模板 drwxr-xr-x 2 yuanye yuanye 4096 2011-03-22 23:25 视频 drwxr-xr-x 2 yuanye yuanye 4096 2011-03-22 23:25 图片 drwxr-xr-x 2 yuanye yuanye 4096 2011-03-22 23:25 文档 drwxr-xr-x 2 yuanye yuanye 4096 2011-03-22 23:25 音乐 drwxr-xr-x 2 yuanye yuanye 4096 2011-03-22 23:25 桌面 3. . .fontconfig .local .Xauthority .. .gconf .mozilla .xsession-errors .bash_logout .gconfd .nautilus 公共的 .bashrc .gksu.lock .profile 模板 .cache .gnome2 .pulse 视频 .chewing .gnome2_private .pulse-cookie 图片 .config .gnupg .recently-used.xbel 文档 .dbus .gstreamer-0.10 .scim 音乐 .dmrc .gtk-bookmarks .sudo_as_admin_successful 桌面 .esd_auth .gvfs .update-manager-core

《网络操作系统(Windows-server-)》实训指导书

目录 《网络操作系统(WINDOWS SERVER 2012)》课程实训指导书 (1) 一、实训目的与要求 (1) 二、实训内容 (1) 三、参考课时 (1) 四、实训考核与组织 (1) 五、说明 (2) 六、实训项目 (2) 实训项目一 WINDOWS SERVER 2012的安装与配置 (3) 实训项目二 DNS域名服务的实现 (5) 实训项目三 DHCP服务器的配置与管理的实现 (8) 实训项目四 WINS服务器的配置 (10) 实训项目五 WINDOWS SERVER 2012活动目录的实现 (12) 实训项目六 WINDOWS SERVER 2012磁盘管理的实现 (16) 实训项目七 WINDOWS SERVER 2012文件管理 (18) 一、实训目的与要求 (18) 实训项目八 IIS服务器的应用实现 (21) 一、实训目的与要求 (21) 在网站中放置一些网页,打开浏览器访问该网站。(在本机上访问可使用“,在其它计算机上访问可使用“ FTP服务器的配置的实现 (22)

《网络操作系统(Windows Server 2012)》课程实训指导书一、实训目的与要求 网络操作系统(Windows Server 2012)实训以Windows Server 2012为操作平台,全面介绍与Windows Server 2012网络系统管理有关的知识和 Windows Server 2012系统管理的基本技能,最终使学生掌握解决一般网络系统管理中遇到的问题的能力。 二、实训内容 Windows Server 2012 网络操作系统实训分为:Windows Server 2012的安装与配置、DNS域名服务的实现、DHCP服务器的配置与管理的实现、WINS服务器的配置、Windows Server 2012的相关管理、以及各种服务器的配置与应用。 三、参考课时 四、实训考核与组织

操作系统原理-进程调度实验报告

一、实验目的 通过对进程调度算法的设计,深入理解进程调度的原理。 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 进程调度分配处理机,是控制协调进程对CPU的竞争,即按一定的调度算法从就绪队列中选中一个进程,把CPU的使用权交给被选中的进程。 进程通过定义一个进程控制块的数据结构(PCB)来表示;每个进程需要赋予进程ID、进程到达时间、进程需要运行的总时间的属性;在RR中,以1为时间片单位;运行时,输入若干个进程序列,按照时间片输出其执行序列。 二、实验环境 VC++6.0 三、实验内容 实现短进程优先调度算法(SPF)和时间片轮转调度算法(RR) [提示]: (1) 先来先服务(FCFS)调度算法 原理:每次调度是从就绪队列中,选择一个最先进入就绪队列的进程,把处理器分配给该进程,使之得到执行。该进程一旦占有了处理器,它就一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。 将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理,是一种最普遍和最简单的方法。它优先考虑在系统中等待时间最长的作业,而不管要求运行时间的长短。 按照就绪进程进入就绪队列的先后次序进行调度,简单易实现,利于长进程,CPU繁忙型作业,不利于短进程,排队时间相对过长。 (2) 时间片轮转调度算法RR

原理:时间片轮转法主要用于进程调度。采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度按一定时间片(q)轮番运行各个进程. 进程按到达时间在就绪队列中排队,调度程序每次把CPU分配给就绪队列首进程使用一个时间片,运行完一个时间片释放CPU,排到就绪队列末尾参加下一轮调度,CPU分配给就绪队列的首进程。 固定时间片轮转法: 1 所有就绪进程按 FCFS 规则排队。 2 处理机总是分配给就绪队列的队首进程。 3 如果运行的进程用完时间片,则系统就把该进程送回就绪队列的队尾,重新排队。 4 因等待某事件而阻塞的进程送到阻塞队列。 5 系统把被唤醒的进程送到就绪队列的队尾。 可变时间片轮转法: 1 进程状态的转换方法同固定时间片轮转法。 2 响应时间固定,时间片的长短依据进程数量的多少由T = N × ( q + t )给出的关系调整。 3 根据进程优先级的高低进一步调整时间片,优先级越高的进程,分配的时间片越长。 多就绪队列轮转法: (3) 算法类型 (4)模拟程序可由两部分组成,先来先服务(FCFS)调度算法,时间片轮转。流程图如下:

《 Windows7 操作系统》实验报告

实验(一) Windows 7基本操作 一、实验目的 1.掌握文件和文件夹基本操作。 2.掌握“资源管理器”和“计算机”基本操作。 二、实验要求 1.请将操作结果用Alt+Print Screen组合键截图粘贴在题目之后。 2.实验完成后,请将实验报告保存并提交。 三、实验内容 1.文件或文件夹的管理(提示:此题自行操作一遍即可,无需抓图)★期末机试必考题★ (1) 在D:盘根目录上创建一个名为“上机实验”的文件夹,在“上机实验”文件夹中创建1个名为“操作系统上机实验”的空白文件夹和2个分别名为“2.xlsx”和“3.pptx”的空白文件,在“操作系统上机实验”文件夹中创建一个名为“1.docx”的空白文件。 (2) 将“1.docx”改名为“介绍信.docx”;将“上机实验”改名为“作业”。 (3) 在“作业”文件夹中分别尝试选择一个文件、同时选择两个文件、一次同时选择所有文件和文件夹。 (4) 将“介绍信.docx”复制到C:盘根目录。 (5) 将D:盘根目录中的“作业”文件夹移动到C:盘根目录。 (6) 将“作业”文件夹中的“2.xlsx”文件删除放入“回收站”。 (7) 还原被删除的“2.xlsx”文件到原位置。 2.搜索文件或文件夹,要求如下: 查找C盘上所有以大写字母“A”开头,文件大小在10KB以上的文本文件。(提示:搜索时,可以使用“?”和“*”。“?”表示任意一个字符,“*”表示任意多个字符。)

3. 在桌面上为C:盘根目录下的“作业”文件夹创建一个桌面快捷方式。★期末机试必考题★ 3.“计算机”或“资源管理器”的使用 (1) 在“资源管理器”窗口,设置以详细信息方式显示C:\WINDOWS中所有文件和文件夹,使所有图标按类型排列显示,并不显示文件扩展名。(提示:三步操作全部做完后,将窗口中显示的最终设置结果抓一张图片即可) (2) 将C:盘根目录中“介绍信.docx”的文件属性设置为“只读”和“隐藏”,并设置在窗口中显示“隐藏属性”的文件或文件夹。(提示:请将“文件夹”对话框中选项设置效果与C:盘根目录中该文件图标呈现的半透明显示效果截取在一整张桌面图片中即可) 4.回收站的设置 设置删除文件后,不将其移入回收站中,而是直接彻底删除功能。

操作系统原理实验四

实验4 进程控制 1、实验目的 (1)通过对WindowsXP进行编程,来熟悉和了解系统。 (2)通过分析程序,来了解进程的创建、终止。 2、实验工具 (1)一台WindowsXP操作系统的计算机。 (2)计算机装有Microsoft Visual Studio C++6.0专业版或企业版。 3、预备知识 (3)·CreateProcess()调用:创建一个进程。 (4)·ExitProcess()调用:终止一个进程。 4、实验编程 (1)编程一利用CreateProcess()函数创建一个子进程并且装入画图程序(mspaint.exe)。阅读该程序,完成实验任务。源程序如下: # include < stdio.h > # include < windows.h > int main(VOID) ﹛STARTUPINFO si; PROCESS INFORMA TION pi; ZeroMemory(&si,sizeof(si)); Si.cb=sizeof(si); ZeroMemory(&pi,sizeof(pi)); if(!CreateProcess(NULL, “c: \ WINDOWS\system32\ mspaint.exe”, NULL, NULL, FALSE, 0, NULL, NULL, &si,&pi)) ﹛fprintf(stderr,”Creat Process Failed”); return—1; ﹜ WaitForSingleObject(pi.hProcess,INFINITE); Printf(“child Complete”); CloseHandle(pi.hProcess); CloseHandle(pi hThread); ﹜

操作系统原理实验-系统内存使用统计5

上海电力学院 计算机操作系统原理 实验报告 题目:动态链接库的建立与调用 院系:计算机科学与技术学院 专业年级:信息安全2010级 学生姓名:李鑫学号:20103277 同组姓名:无 2012年11 月28 日上海电力学院

实验报告 课程名称计算机操作系统原理实验项目线程的同步 姓名李鑫学号20103277 班级2010251班专业信息安全 同组人姓名无指导教师姓名徐曼实验日期2012/11/28 实验目的和要求: (l)了解Windows内存管理机制,理解页式存储管理技术。 (2)熟悉Windows内存管理基本数据结构。 (3)掌握Windows内存管理基本API的使用。 实验原理与内容 使用Windows系统提供的函数和数据结构显示系统存储空间的使用情况,当内存和虚拟存储空间变化时,观察系统显示变化情况。 实验平台与要求 能正确使用系统函数GlobalMemoryStatus()和数据结构MEMORYSTATUS了解系统内存和虚拟空间使用情况,会使用VirtualAlloc()函数和VirtualFree()函数分配和释放虚拟存储空间。 操作系统:Windows 2000或Windows XP 实验平台:Visual Studio C++ 6.0 实验步骤与记录 1、启动安装好的Visual C++ 6.0。 2、选择File->New,新建Win32 Console Application程序, 由于内存分配、释放及系统存储 空间使用情况均是Microsoft Windows操作系统的系统调用,因此选择An application that support MFC。单击确定按钮,完成本次创建。 3、创建一个支持MFC的工程,单击完成。

操作系统上机实验报告

大连理工大学实验报告 学院(系):专业:班级: 姓名:学号:组:___ 实验时间:实验室:实验台: 指导教师签字:成绩: 实验名称:进程控制 一、实验目的和要求 (1)进一步加强对进程概念的理解,明确进程和程序的区别 (2)进一步认识并发执行的实质 二、实验环境 在windows平台上,cygwin模拟UNIX运行环境 三、实验内容 (1) getpid()---获取进程的pid 每个进程都执行自己独立的程序,打印自己的pid; (2) getpid()---获取进程的pid 每个进程都执行自己独立的程序,打印自己的pid; 父进程打印两个子进程的pid;

(3)写一个命令处理程序,能处理max(m,n), min(m,n),average(m,n,l)这几个命令(使用exec函数族)。 Max函数 Min函数 Average函数 Exec函数族调用 四、程序代码 五、运行结果 六、实验结果与分析 七、体会 通过这次上机,我了解了fork函数的运行方法,同时更深刻的了解了进程的并行执行的本质,印证了在课堂上学习的理论知识。同时通过编写实验内容(3)的命令处理程序,学会了exec函数族工作原理和使用方法。通过这次上机实验让我加深了对课堂上学习的理论知识的理解,收获很多。

大连理工大学实验报告 学院(系):专业:班级: 姓名:学号:组:___ 实验时间:实验室:实验台: 指导教师签字:成绩: 实验名称:进程通讯 一、实验目的和要求 了解和熟悉UNIX支持的共享存储区机制 二、实验环境 在windows平台上,cygwin模拟UNIX运行环境 三.实验内容 编写一段程序, 使其用共享存储区来实现两个进程之间的进程通讯。进程A创建一个长度为512字节的共享内存,并显示写入该共享内存的数据;进程B将共享内存附加到自己的地址空间,并向共享内存中写入数据。 四、程序代码 五、运行结果 六、实验结果与分析 七、体会

操作系统实验报告生产者与消费者问题模拟

操作系统上机实验报告 实验名称: 生产者与消费者问题模拟 实验目的: 通过模拟生产者消费者问题理解进程或线程之间的同步与互斥。 实验内容: 1、设计一个环形缓冲区,大小为10,生产者依次向其中写入1到20,每个缓冲区中存放一个数字,消费者从中依次读取数字。 2、相应的信号量; 3、生产者和消费者可按如下两种方式之一设计; (1)设计成两个进程; (2)设计成一个进程内的两个线程。 4、根据实验结果理解信号量的工作原理,进程或线程的同步\互斥关系。 实验步骤及分析: 一.管道 (一)管道定义 所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。(二)所涉及的系统调用 1、pipe( ) 建立一无名管道。 系统调用格式 pipe(filedes) 参数定义 int pipe(filedes); int filedes[2]; 其中,filedes[1]是写入端,filedes[0]是读出端。 该函数使用头文件如下: #include #inlcude #include 2、read( ) : 系统调用格式 read(fd,buf,nbyte) 功能:从fd所指示的文件中读出nbyte个字节的数据,并将它们送至由指针buf 所指示的缓冲区中。如该文件被加锁,等待,直到锁打开为止。 参数定义:

int read(fd,buf,nbyte); int fd; char *buf; unsigned nbyte; 3、write( ) 系统调用格式 read(fd,buf,nbyte) 功能:把nbyte 个字节的数据,从buf所指向的缓冲区写到由fd所指向的文件中。如文件加锁,暂停写入,直至开锁。 参数定义同read( )。 (三)参考程序 #include #include #include int pid1,pid2; main( ) { int fd[2]; char outpipe[100],inpipe[100]; pipe(fd); /*创建一个管道*/ while ((pid1=fork( ))==-1); if(pid1==0) { lockf(fd[1],1,0); /*把串放入数组outpipe中*/ sprintf(outpipe,child 1 is using pipe!); /* 向管道写长为50字节的串*/ write(fd[1],outpipe,50); sleep(5); /*自我阻塞5秒*/ lockf(fd[1],0,0); exit(0); } else { while((pid2=fork( ))==-1); if(pid2==0) { lockf(fd[1],1,0); /*互斥*/ sprintf(outpipe,child 2 is using pipe!); write(fd[1],outpipe,50); sleep(5); lockf(fd[1],0,0);

网络操作系统实验报告

一、实验目的 1. 掌握UNIX系统的目录和文件管理命令。 2. 掌握shell的输入输出重定向操作符。 3. 编写shell脚本文件,并调试、执行它。 二、实验要求 1.要求每人能独立完成实验。能独立搭建UNIX操作系统,掌握OpenSolaris的安装、 运行和使用。 2.使用自己的账号登录UNIX 系统, 用户名为:学号和姓名汉语拼音全拼。在用户主 目录下,新建子目录,子目录名为:专业和班级(可以是拼音)。 3.在新建的子目录下完成全部练习,所有的操作练习均要完整截图显示。 4.所有的实验内容必须在命令行方式下进行操作。 5.纸制版的封面单面打印,其他页面必须双面打印。全班刻一张光盘。 三、实验内容 1.用uname -a命令显示操作系统的版本。 2.用pwd命令显示用户主目录的路径名。 3.用date命令查看当前日期和时间。分别比较%w和%a,%y和%D。 4.用who命令查看当前登录在系统中的用户列表。利用who命令选项查看当前系统中的 用户总数和系统起动时间。比较who am I 、whoami 和who am i显示的结果区别。 5.用vi编辑器,先在用户主目录中创建名为notes的会议通知文件,编辑notes文件。(1) 统计文件大小,(2)重新编辑文件notes,加上一个适当的标题,(3)修改notes中开会的时间和地点。(说明notes文件内容不能以数字和简单的字母组成,必须是一段有内容的英文,至少是10行以上的描述) 6.用find命令查找名为passwd的文件。从用户主目录开始,查找所有1天前创建的文件。 寻找所有名为xyz大小为20个文件块的文件。查找所有修改过的文件。 7.用重定向符和cat命令创建一个unm脚本文件完成如下功能。并运行它。 a.显示用户名。 b.显示用户的主机名。 c.显示当前shell名称。 d.打印出当前目录名并列出目录中的文件信息。 8.编写简单的C程序,编译和运行程序。用c语言程序编程实现:将no1.tar文件解压, 得到file1和file2,然后通过文件读取函数读取file1和file2的内容,合并两部分的内容并输出到新的文件newfile中。 9.编写Java程序,编译和运行程序。在Applet中做两个提示标签,两个输入文本框,分 别输入两个数,回车后在paint()方法中计算并暗淡无光它们加减乘除的结果(要求字体大小、显示颜色不用缺省的)。

操作系统原理实验五

实验五线程的同步 1、实验目的 (1)进一步掌握Windows系统环境下线程的创建与撤销。 (2)熟悉Windows系统提供的线程同步API。 (3)使用Windows系统提供的线程同步API解决实际问题。 2、实验准备知识:相关API函数介绍 ①等待对象 等待对象(wait functions)函数包括等待一个对象(WaitForSingleObject ())和等待多个对象(WaitForMultipleObject())两个API函数。 1)等待一个对象 WaitForSingleObject()用于等待一个对象。它等待的对象可以为以下对象 之一。 ·Change ontification:变化通知。 ·Console input: 控制台输入。 ·Event:事件。 ·Job:作业。 ·Mutex:互斥信号量。 ·Process:进程。 ·Semaphore:计数信号量。 ·Thread:线程。 ·Waitable timer:定时器。 原型: DWORD WaitForSingleObject( HANDLE hHandle, // 对象句柄 DWORD dwMilliseconds // 等待时间 ); 参数说明: (1)hHandle:等待对象的对象句柄。该对象句柄必须为SYNCHRONIZE访问。 (2)dwMilliseconds:等待时间,单位为ms。若该值为0,函数在测试对象的状态后立即返回,若为INFINITE,函数一直等待下去,直到接收到 一个信号将其唤醒,如表2-1所示。 返回值: 如果成功返回,其返回值说明是何种事件导致函数返回。

Static HANDLE hHandlel = NULL; DWORD dRes; dRes = WaitForSingleObject(hHandlel,10); //等待对象的句柄为hHandlel,等待时间为10ms 2)等待对个对象 WaitForMultiple()bject()在指定时间内等待多个对象,它等待的对象与 WaitForSingleObject()相同。 原型: DWORD WaitForMultipleObjects( DWORD nCount, //句柄数组中的句柄数 CONST HANDLE * lpHandles, //指向对象句柄数组的指针 BOOL fWaitAll, //等待类型 DWORD dwMilliseconds //等待时间 ); 参数说明: (1)nCount:由指针 * lpHandles指定的句柄数组中的句柄数,最大数是MAXIMUM WAIT OBJECTS。 (2)* lpHandles:指向对象句柄数组的指针。 (3)fWaitAll:等待类型。若为TRUE,当由lpHandles数组指定的所有对象被唤醒时函数返回;若为FALSE,当由lpHandles数组指定的某一个 对象被唤醒时函数返回,且由返回值说明是由于哪个对象引起的函数 返回。 (4)dwMilliseconds:等待时间,单位为ms。若该值为0,函数测试对象的状态后立即返回;若为INFINITE,函数一直等待下去,直到接收到 一个信号将其唤醒。 返回值:、 如果成功返回,其返回值说明是何种事件导致函数返回。 各参数的描述如表2-2所示。

操作系统原理实验十一

实验十一银行家算法模拟实现 1实验类型 设计型(4学时)。 2实验目的 1)理解死锁避免相关内容; 2)掌握银行家算法主要流程; 3)掌握安全性检查流程。 3实验描述 本实验主要对操作系统中的死锁预防部分的理论进行实验。要求实验者设计一个程序,该程序可对每一次资源申请采用银行家算法进行分配。 4实验内容 1)设计多个资源(≥3); 2)设计多个进程(≥3); 3)设计银行家算法相关的数据结构; 4)动态进行资源申请、分配、安全性检测并给出分配结果。 5实验要求 1)编写程序完成实验内容; 2)画出安全性检测函数流程图; 3)小组派1人上台用PPT演讲实现过程; 4)撰写实验报告。

6测试要求 1)进行Request请求,输入参数为进程号、资源号和资源数; 2)进行3次以上的Request请求; 3)至少进行1次资源数目少于可用资源数,但不安全的请求。 7相关知识 7.1银行家算法的数据结构 1)可利用资源向量Available。其中每个元素代表每类资源的数目。 2)最大需求矩阵Max。其中每个元素代表每个进程对于每类资源的最大需求量。 Max[i,j]=K表示i进程对于j类资源的最大需求量为K。 3)分配矩阵Allocation。其中每个元素代表每个进程已得到的每类资源的数目。 4)需求矩阵Need。其中每个元素代表每个进程还需要的每类资源的数目。 7.2银行家算法 Request i [j]=K表示进程Pi需要K个j类资源。 1)如果Request i [j]≤Need[i , j],便转向步骤2,否则认为出错。 2)如果Request i [j]≤Available[j],便转向步骤3,否则表示无足够资源,Pi需等待; 3)系统尝试分配资源给Pi; 4)系统进行安全性检查,检查此次资源分配后,系统是否安全。如果安全,则正式分配资源,否则撤销此次分配。 7.3安全性算法 1)设置两个向量:工作向量Work和Finish。算法开始时Work=Available;Finish 表示系统是否有足够的资源分配给进程,使之运行完成,开始时,令 Finish[i]=False;如果有足够的资源分配给进程,则令Finish[i]=True。 2)从进程集合中找到一个能满足下列条件的进程:Finish[i]=False;Need[i,j] ≤Work[j],若找到,执行步骤3),否则,执行步骤4); 3)Pi获得所需资源后,可顺利执行指导完成,并释放它占有的资源。并执行:Work[j]=Work[j]+Allocation[i , j]; Finish[i] = True; 到第2)步。

操作系统实验报告18038

福州大学数学与计算机科学(软件)学院 实验报告 课程名称:计算机操作系统 学号:221100218 姓名: 专业:软件工程 年级:2011级 学期:2012学年第2学期 2013年10 月24 日

实验一 Linux操作系统的使用和分析 一、实验目的 本实验主要学习和掌握Linux操作系统的基本应用。通过本实验,学生能够熟练掌握Linux环境下各种基本操作命令接口的应用。从系统安全角度出发,学习掌握系统的基本安全优化和配置,在操作系统层次进行有效安全加固,提高Linux系统的安全性能。通过本次实验,有助于学生进一步理解操作系统原理中的相关内容,加深认识。 二、实验要求 1、熟练掌握Linux系统的基本操作命令。 2、熟悉Linux 系统的基本配置。 3、实现Linux系统的安全加固。 4、掌握一种以上的网络应用软件的安装、配置与应用。 三、实验内容 系统的启动,如图: 关闭使用shutdowm 还有列出文件夹内的信息ls,cp复制拷贝,touch创建文件命令等等 ①下载文件压缩包pro.gz,解压如图:

②然后修改安装路径: ③之后用make编译文件 ④在安装路径/home/liaoenrui/11里的etc中修改文件的组名和用户名: 将groud 命名也命名为ftp,然后用groudadd和useradd命令将这两个添加在该目录的sbin目录下:

⑤最后运行文件,./profile即可 四、实验总结 通过本次的操作系统的上机实验,我熟练了Linux系统的基本操作命令,并且对安装文件有更深入的了解,比如在上述安装过程中对于通过froftpd来架构linux的ftp,由于之前都是用window系统,所以对于这些非常的生疏,因此在请教了多人和上网查询之后,终于有所了解,并且成功的将此实验顺利完成。在本次实验中,我发现自己的动手能力又有很大的提高,相信以后继续努力的话会有更大的进步,当然这也要归功于老师的教导。 参考文献 [1] Neil Maththew Richard Stones Linux 程序设计第四版人民邮电出版社 [2] 周茜,赵明生.中文文本分类中的特征选择研究[J].中文信息学报,2003,Vol.18 No.3

网络操作系统实验报告,LINUX操作系统

实验项目一安装Linux系统 一、实验目的和要求: (一)目的: 1、了解Linux系统的安装方法 2、掌握Linux系统安装步骤 3、了解Linux系统界面 (二)要求: 1、熟练掌握Linux系统安装 2、熟悉Linux的系统界面 二、实验时数:8 三、实验器材: 计算机、虚拟机软件、Linux光盘 实验原理:Linux系统安装是学会使用Linux系统的基础 日期:第一周至第二周 四、实验内容或步骤: (一)内容:Linux系统安装 (二)步骤: 1、新建一个虚拟机,选择安装系统类型Linux,选择安装目录; 2、放入Linux第一张光盘; 3、选择安装向导所用语言 4、选择键盘类型 5、选择鼠标类型 6、选择安装类型,如“个人桌面” 7、磁盘分区设置是关键的一步如果选“自动分区”后,点击“下一步” 8、引导装载程序配置 9、设置网络,如果不清楚亦可以后进系统后再配置, 10、防火墙配置一般用途选“中级”就可以了 11、选择系统默认语言选中“Chinese(P.R.of China)”简体中文 12、时区选“亚洲/上海” 13、设置根口令即root管理员密码 14、一个慢长的安装过程已经开始, 15、第一张光盘中安装完成,插入第二张光盘,完成后再更换第三张光盘

16、正确选择核对显卡型号 17正确选择核对显示器型号 18安装已完成,系统将重新启动, 19输入帐号“root”、密码进入系统图形界面了 20、观察和了解Linux系统界面。 五、注意事项: 1、手动分区时,/SWAP最少为内存的2倍大小。 六、练习项目及思考题(讨论或习题): 1、使用自动分区方式安装Linux系统。 2、使用手动分区方式安装Linux系统。

《操作系统原理实验》试卷A及答案

《中山大学授予学士学位工作细则》第六条 考试作弊不授予学士学位 计算机科学系2012第二学期 《操作系统原理实验》期末考试试题(A) 任课教师:李才伟考试形式:开卷考试时间:2小时年级:11 班别:3 专业:计科姓名:________ 学号:___ _ 成绩___ _ 注意:答案一定要写在答卷中,写在本试题卷中不给分。本试卷要和答卷一起交回。 一.填空题(每小题2分,共30分) 1.在我们的操作系统实验中,C与汇编语言混合编程的操作系统环境为___,其所用的虚拟机为___。2.测试用软盘映像文件的大小为___MB,使用的文件系统格式为___。 3.Intel 80386新增加的两个段寄存器分别为___和___。 4.Intel处理器实模式下的中断向量表包含___个中断向量,每个中断向量有___位。 5.Linux中挂载磁盘映像的命令为___,C语言的编译器为___。 6.将程序的入口安排在指定位置的汇编操作符为___、LD的链接选项为___。 7.ELF的英文原文是___,中文译文为___。 8.在FAT的文件条目中,普通文件和子目录的文件属性值分别为___和___。 9.在IA-32的保护模式下,分段用于___,分页用于___。 10.IA-32处理器的4个系统地址寄存器分别为___。 11.IA-32中的描述符和选择符大小分别为___位和___位。 12.TSS的主要功用为___,TSS描述符只能位于___描述符表中。 13.控制保护模式的寄存器为___,激活保护标志位于其___位。 14.IA-32的三种特权级类型分别为___、___和___。 15.在Make文件中,$@ 和$< 分别表示___和___。 二.问答题(每小题5分,共30分) 1.在实模式下的进程调度中是如何实现堆栈切换的? 2.IA-32的保护模式相比实模式的主要优点有哪些? 3.给出IA-32保护模式下的段寄存器的内容、组成和功用。 4.给出GDT和LDT的英文原文和中文译文,它们有哪些主要功用和区别? 5.启动分页机制的主要步骤有哪些? 6.给出IA-32段页式保护模式下(采用4KB页面大小与两级分页方式的)逻辑地址和线性地址的构成及转 换成物理地址的方法。

《大学计算机基础》上机实验报告

《大学计算机基础》 上机实验报告 班级: 姓名: 学号: 授课教师: 日期:年月日

目录 一、Windows操作系统基本操作 ............................. - 1 - 二、Word文字处理基本操作 ................................ - 4 - 三、Excel电子表格基本操作 ............................... - 6 - 四、PowerPoint幻灯片基本操作 ............................ - 8 - 五、网页设计基本操作..................................... - 9 - 六、Access数据库基本操作 ............................... - 10 - 上机实验作业要求: ○1在实验报告纸上手写并粘贴实验结果; ○2每人将所有作业装订在一起(要包封面); ○3全部上机实验结束后全班统一上交; ○4作业内容不得重复、输入的数据需要有差别。

实验名称一、Windows操作系统基本操作 实验目的1、掌握Windows的基本操作方法。 2、学会使用“画图”和PrntScr快捷键。 3、学会使用“计算器”和Word基本操作。 实验内容 1、日历标注 利用“画图”和Word软件,截取计算机上日历的图片并用文字、颜色、图框等标注出近期的节假日及其名称,并将结果显示保存在下面(参考下面样图)。 运行结果是: 主要操作步骤是: 2、科学计算 利用“计算器”和Word软件,计算下列题目,并将结果截图保存在下面(参考样图)。 ○1使用科学型计算器,求8!、sin(8)、90、74、20、67、39、400、50.23、ln(785)的平均值、和值,并用科学计数法显示。 运行结果是: ②将以下十、八、十六进制数转换为二进制数:(894.8125)10、(37.5)8、(2C.4B)16 运行结果是:(需要下载使用“唯美计算器”) ○3计算下列二进制数的加法与乘法:101.1+11.11;1101*1011 运行结果是:(参考样图) 写出主要操作步骤: 3、实验心得体会

操作系统原理实验2+岳青山+0907052247

《操作系统原理》实验报告 实验序号:2 实验项目名称: Windows 基本进程管理 1、实验目的 通过观察任务管理器,来观察各个进程的动态信息。 2、实验工具 (1)一台WindowsXP操作系统的计算机。 (2)计算机装有Microsoft Visual Studio C++6.0专业版或企业版。 3、预备知识 ·任务管理器,了解用户计算机上正在运行的程序和进程的相关信息。 ·Windows环境中的编程。 相关内容参见本次实验参考资料部分。 4、基本实验 1)观察任务管理器 步骤一:进入WindowsXP。 步骤二:按Ctrl+Alt+Delete(或按Ctrl+Shift+Esc)键都可以调出任务管理器。 步骤三:单击“查看”→“选择列”选项,可以看到一些选项, 这里,可以查看每个进程的PID,CPU使用时间,内存的使用情况,当前的进程是系统的还是用户的,每个句柄的数量,每个进程的优先级,等等。 步骤四:单击“性能”标签,在所示的“性能”选项卡中可以看到CPU的使用情况、内存的使用情况。 2)通过命令观察进程情况、 步骤一:单击“开始”→“运行”选项,输入cmd“命令提示符”下。 步骤二:输入tasklist。 步骤三:继续输入tasklist/?来寻找帮助,里面有更详细的解释。 3)通过命令来关闭一个进程 步骤一:单击“开始”→“运行”选项,输入cmd“命令提示符”下。 步骤二:输入tasklist后回车执行。 步骤三:继续输入taskkill/PID 208/T 5、实验编程 进行一个简单的Windows的图形用户接口(GUI)编程。 步骤一:进入WindowsXP。 步骤二:进入Microsoft Visual Studio C++6.0。 步骤三:在菜单栏中单击“文件”→“新建”→“文件”→C++Source File,选择路径(如D:\1.cpp),并命名为1.cpp。 步骤四:将下面的程序源代码输入。 步骤五:单击Windows系统的“开始”→“运行”选项,输入cmd。

网络操作系统实验报告汇总

网络操作系统实验报告 姓名:李文超 学号:1200007934 班级:网络1217 学院:计算机信息学院

虚拟机VMware Workstation的安装及使用实验报告 1、实验目的 使学生们掌握虚拟机的安装及使用 2、实验内容 (1)虚拟机VMware Workstation安装 (2)安装VM Tools (3)虚拟机的网络配置及虚拟机的操作使用 3、实验步骤 1)虚拟机VMware Workstation安装 (VMware9.0.1安装步骤: 第一步:双击以上文件进入以下界面 第二步:单击上图的Next(下一步)进入以下界面 进入安装类型选择窗口,在Typical”和“Custom”两种选项中选择安装方式;

第三步:选择上图的Typical或Custom()这时Next(下一步)按钮由淡灰色变为淡蓝色,单击Next(下一步)。 第四步:单击上图的Change更换安装盘(也可以默认),选好就单击Next(下一步)

第五步:Next(下一步) 第六步:单击Next(下一步) 选择“Custom”安装方式后,自定义安装相关的组件,进入“Configure Shortcuts”

窗口,选择运行此软件的快捷方式:桌面、开始菜单以及快速启动工具栏; 第七步:单击Next(下一步) 第八步:单击Continue(继续)

第九步:输入Key 下面的Key供参考: JV0GK-8C3EM-5ZD21-U89NM-03K0L 5G47N-48H13-VZX61-728Q2-93TJX 5F4JV-A804M-4Z421-0V1N2-33EMY 0V6UY-4Z29L-8ZNQ1-R80QK-ACWL6 MZ2RU-D1K50-PZAX9-UK176-82Q7H 4A25F-4010Q-5ZQJ9-21CNH-AA TJH 最后Enter 第十步:单击Finish(完成)

操作系统原理实验报告

操作系统原理 实验报告 学院:信息与电子工程学院专业:计算机科学与技术 班级:计算机 学号: 姓名: 浙江科技学院 2010-2011学年第2学期

实验1 进程管理 一、实验目的 1. 弄清进程和程序的区别,加深对进程概念的理解。 2. 了解并发进程的执行过程,进一步认识并发执行的实质。 3. 掌握解决进程互斥使用资源的方法。 二、实验内容 1. 管道通信 使用系统调用pipe( )建立一个管道,然后使用系统调用fork( )创建2个子进程p1和p2。这2个子进程分别向管道中写入字符串:“Child process p1 is sending message!”和“Child process p2 is sending message!”,而父进程则从管道中读出来自两个子进程的信息,并显示在屏幕上。 2. 软中断通信 使用系统调用fork( )创建2个子进程p1和p2,在父进程中使用系统调用signal( )捕捉来自键盘上的软中断信号SIGINT(即按Ctrl-C),当捕捉到软中断信号SIGINT后,父进程使用系统调用kill( )分别向2个子进程发出软中断信号SIGUSR1和SIGUSR2,子进程捕捉到信号后分别输出信息“Child process p1 is killed by parent!”和“Child process p2 is killed by parent!”后终止。而父进程等待2个子进程终止后,输出信息“Parent process is killed!”后终止。 三、实验要求 1. 根据实验内容编写C程序。 2. 上机调试程序。 3. 记录并分析程序运行结果。

网络操作系统综合实验

重庆科技学院 综合实验报告 课程名称:网络操作系统__ 开课学期:_2010-2011-2_ _学院:_电气与信息工程学院_开课实验室:计算机专业实验室学生姓名: _ ________ 专业班级:__计科应08___ 学号:_ ______

重庆科技学院学生实验报告 当今网络化的世界中,计算机信息和资源很容易遭到各方面的攻击。网络的开放性和共享性在方便了人们使用的同时,也使得网络很容易遭到攻击,而攻击的后果是严重的,诸如数据被人窃取、服务器不能提供服务等等。随着信息技术的高速发展,网络安全技术也越来越受到重视,由此推动了防火墙、入侵检查、虚拟专用网、访问控制等各种网络安全技术的蓬勃发展。 VLAN技术:选择VLAN技术可较好地从链路层实施网络安全保障。VLAN指通过交换设备在网络的物理拓扑结构基础上建立一个逻辑网络,他依据用户的逻辑设定将原来物理上互连的一个局域网划分为多个虚拟子网,划分的依据可以是设备所连端口、用户节点的MAC地址等。该技术能有效地控制网络流量、防止广播风暴,还可以利用MAC层的

数据包过滤技术,对安全性要求高的VLAN端口实施MAC帧过滤。而且,即使黑客攻破其中一个虚拟子网,也无法得到整个网络的信息。 网络分段:企业网大多采用以广播为基础的以太网,任何两个节点之间的通讯数据包,可以处在同一以太网上的任何一个节点的网卡所截取。因此,黑客只要接入以太网上的任一节点进行侦听,就可以获取发生在这个以太网上的所有数据包,对其进行解包分析,从而窃取关键信息。网络分段就是将非法用户与网络资源相互隔离,从而达到限制用户非法访问的目的。 硬件防火墙技术:任何企业安全策略的一个主要部分都是实现和维护防火墙,因此防火墙在网络安全的实现当中扮演着重要的角色。防火墙通常位于企业网络的边缘,这使得内部网络与Internet是为了在内部网与外部网之间设立唯一的通道,简化网络的安全管理。 入侵检测技术:入侵检测方法较多,如基于专家系统入侵检测方法、基于神经网络的入侵检测方法等。目前一些入侵检测系统在应用层入侵检测中已有实现。 Windows Server 2003作为Mircrosoft推出的服务器操作系统,不仅继承了Windows 2000/XP的易用性和稳定性,而且还提供了更高的硬件支持和更加强大的安全功能,无疑是中小型网络应用服务器的当然之选。 三、主要仪器设备 1.每8人一组,每组一套网络设备(含交换机、PC) 2.每人一台电脑 3.网线若干 四、实验操作方法和步骤 4.1提高密码的破解难度 提高密码的破解难度主要是通过采用提高密码复杂性、增大密码长度、提高更换频率等措施来实现,但常常是用户很难做到的,对于企业网络中的一些安全敏感用户就必须采取一些相关的措施,以强制改变不安全的密码使用习惯。 首先安装域控制器,然后在开始->管理工具->域安全策略打开如下图所示的界面如图4.1所示、 然后再在打开安全设置->账户锁定策略->账户锁定阀值,右击属性,设置登录次数为4次,然后在开机的时候如果设置了密码,输入密码输了四次仍然不对则系统会锁定,不能再登录了。

相关文档
相关文档 最新文档