Windows环境下线程管理与同步互斥实验

需积分: 10 7 下载量 43 浏览量 更新于2024-09-09 收藏 67KB DOCX 举报
"该实验是关于Windows系统的进程管理,特别是线程的创建、撤销、同步和互斥。实验目标是让学习者熟悉Visual C++ 6.0开发环境,掌握如何在Windows环境下创建和撤销线程,以及实现线程间的同步和互斥。通过创建两个子线程并使用互斥信号量实现对共享变量的安全访问,从而理解线程调度的基本原理。" 实验1的详细知识点包括: 1. **线程创建与撤销**:在Windows系统中,可以使用`CreateThread`函数来创建线程。该函数接受参数,如线程属性、线程入口点函数、传递给新线程的数据等。撤销线程通常不是必要的,因为线程在完成执行后会自动终止。但可以通过`TerminateThread`强制终止线程,不过这在大多数情况下不推荐,因为它可能导致数据丢失和系统不稳定。 2. **线程同步**:线程同步是确保多线程程序中不同线程按照预定顺序或协调执行的过程。在示例代码中,使用了`CreateMutex`创建一个互斥信号量`g_hMutex`,确保只有一个线程能访问临界区(即共享资源)。`WaitForSingleObject`函数用于等待互斥体的使用权,而`ReleaseMutex`则释放使用权,允许其他线程进入。 3. **线程互斥**:线程互斥是线程同步的一种方式,它保证同一时间只有一个线程可以访问特定的资源。在实验的源代码中,两个子线程`func1`和`func2`都试图修改共享变量`count`。通过使用互斥信号量,确保在任何时刻只有一个线程能够更新`count`,避免了数据竞争问题。 4. **线程调度**:在Windows环境下,线程调度由操作系统内核负责,它根据优先级和当前状态决定哪个线程应该获得CPU执行权。实验中的`Sleep`函数被用来模拟线程执行的不同耗时,从而影响线程调度的效果。 5. **Visual C++ 6.0**:这是一个经典的C++集成开发环境,尽管现在已经较老,但它仍然是学习Windows API和多线程编程的一个良好工具。实验要求学生熟悉这个环境,以便编写和调试代码。 6. **线程句柄**:在Windows中,每个线程都有一个唯一的句柄标识符,如`h1`和`h2`,可以用来管理和操作线程,例如获取线程状态或终止线程。 实验代码中,`func1`和`func2`线程通过调用`WaitForSingleObject`和`ReleaseMutex`来实现对`count`的互斥访问。每个线程在进入临界区前先等待互斥锁,执行完对`count`的修改后,释放锁以允许其他线程继续执行。这种设计确保了`count`的正确递增,防止了数据冲突。
2014-04-08 上传
#include #include "dos.h" #include "stdlib.h" #include "conio.h" //PCB结构体 struct pcb{ int id; //进程序号 int ra; //所需资源A的数量 int rb; //所需资源B的数量 int rc; //所需资源C的数量 int ntime; //所需的时间片个数 int rtime; //已经运行的时间片个数 char state; //进程状态 struct pcb *next; } *hready=NULL,*hblock=NULL,*p; //hready,hblock分别为指向就绪和阻塞队列 typedef struct pcb PCB; int m,n,r,a,b,c,h=0,i=1,time1Inteval; //m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //建立一个PCB结构体型的空链表 PCB *increat(void) { PCB *head=NULL; //head=NULL; return(head); } //从链表起始地址开始输出该链表的内容 void disp(PCB *head) {PCB *p1; p1=head; AnsiString str2; if(head!=NULL) //链表非空 { do { str2+=" "; str2+=IntToStr(p1->id);str2+=" "; str2+=(p1->state);str2+=" "; str2+=IntToStr(p1->ra);str2+=" "; str2+=IntToStr(p1->rb);str2+=" "; str2+=IntToStr(p1->rc);str2+=" "; str2+=IntToStr(p1->ntime);str2+=" "; str2+=IntToStr(p1->rtime);str2+="\r\n"; p1=p1->next; }while(p1!=NULL); //不断输出进程的信息,直到链尾! } //if else { str2+="\t\t该 队 列 中 没 有 进 程!\r\n" ;} Form1->Memo1->Lines->Add(str2); } //将进程插入到链尾(包括就绪队列和阻塞队列) PCB *insert(PCB *head,PCB*pcb) //带两个指针形参:队列指针和当前进程PCB { PCB *pi,*p1; p1=head; pi=pcb; if (head==NULL) { head=pi; pi->next=NULL; } else { while(p1->next!=NULL) {p1=p1->next;} p1->next=pi; pi->next=NULL; } return(head); } //对进程进行初始化,建立就绪队阻塞队列。 void input() { AnsiString str1; m=StrToInt (Form1->Edit1->Text); //读取要模拟的进程总数给m n=StrToInt (Form1->Edit2->Text); //读取需初