实验2:线程与同步(解答)

实验2:线程与同步(解答)
实验2:线程与同步(解答)

实验二线程与同步

一、实验目的

1.理解线程的基本概念

2.掌握Java中线程类与Runnable接口的应用

3.掌握控制线程基本方法

4.掌握Java中线程的同步与互斥的实现

二、实验内容

1.验证课堂练习的结果,下面是课堂练习的内容:

(1)编写一个程序,能够根据用户的输入的数值生成相应数目的线程,每个线程运行1秒后结束。

(2)编写一个程序,能够生成n个线程,每个线程每隔1秒打印自己的序号,当用户输入m后第m个线程结束。

(3)编写一个程序,能够生成n个线程,每个线程打印自己的序号后结束,但要求最终的打印的结果为n,n-1,……1。

2.将第三题改写为能够按照任意顺序结束。

3.编写一个程序(由若干个类组成),该程序能够生成3个线程,其中2个线程向一个队列中写入数据,每次写入1个字节,1个线程从队列中读出数据,一次2个字节。

要求读写交替运行,并注意数据的同步,而且队列要借助数组实现。

三、实验步骤

1.运行Eclipse,在其中新建一个Java工程JavaNetwork;

2.创建package https://www.360docs.net/doc/774494614.html,b2,并在其中创建一个Java类FirstThread并运行查看结果,其代码如下:

package https://www.360docs.net/doc/774494614.html,b2;

import java.io.*;

public class FirstThread extends Thread{

public static void main(String[] args) {

int n;

try {

n=Integer.parseInt((new BufferedReader( new InputStreamReader(System.in))).readLine());

for (int i=0;i

(new FirstThread()).start();

}

} catch (IOException e) {

e.printStackTrace();

}

}

public void run(){

System.out.println("Thread started....");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("Thread ended.");

}

}

运行该程序后,程序会等待用户的输入,如果用户输入:3

结果将会是:

Thread started....

Thread started....

Thread started....

Thread ended.

Thread ended.

Thread ended.

即程序会根据用户输入的数值来生成相应数目的线程,每个线程运行1秒后结束。3.在package https://www.360docs.net/doc/774494614.html,b2中创建一个Java类SecondThread并运行查看结果,其代码如下:package https://www.360docs.net/doc/774494614.html,b2;

import java.io.*;

public class SecondThread extends Thread{

private int id;

private boolean flag=true;

private static SecondThread t[];

private static int n=5;

public SecondThread(int id){

this.id=id;

}

public void stopThread(){

flag=false;

}

public boolean getThreadState(){

return flag;

}

public static void main(String[] args) {

int m;

t=new SecondThread[n];

for (int i=0;i

(t[i]=new SecondThread(i)).start();

}

while(testThreads()){

try {

m=Integer.parseInt((new BufferedReader(

new InputStreamReader(System.in))).readLine());

t[m].stopThread();

} catch (IOException e) {

e.printStackTrace();

}

}

System.out.println("program ended.");

}

public void run(){

System.out.println("Thread "+id+" started....");

while (flag){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println("Thread "+id+" ended.");

}

private static boolean testThreads(){

boolean flag=false;

for (int i=0;i

flag|=t[i].getThreadState();

}

return flag;

}

}

运行该程序后,屏幕将首先出现:

Thread 0 started....

Thread 1 started....

Thread 2 started....

Thread 3 started....

Thread 4 started....

然后等待用户输入,如果这时用户依次输入0、3、2、1、4,屏幕将依次出现0

Thread 0 ended.

3

Thread 3 ended.

2

Thread 2 ended.

1

Thread 1 ended.

4

program ended.

Thread 4 ended.

即程序会根据用户输入的数值来结束相应序号的线程,所有线程结束后程序结束。

4.在package https://www.360docs.net/doc/774494614.html,b2中创建一个Java类ThirdRunnable并运行查看结果,其代码如下:package https://www.360docs.net/doc/774494614.html,b2;

public class ThirdRunnable implements Runnable{

private int id;

private static int stopid=-1;

static int n=10;

public ThirdRunnable(int id){

this.id=id;

}

public static void main(String[] args) {

for (int i=1;i<=n;i++){

new Thread(new ThirdRunnable(i)).start();

}

stopid=n;

}

public void run(){

System.out.println("Thread "+id+" started....");

while (id!=stopid){

Thread.yield();

}

System.out.println("Thread "+id+" ended.");

stopid--;

}

}

运行该程序后,屏幕将出现:

Thread 1 started....

Thread 2 started....

Thread 3 started....

Thread 4 started....

Thread 5 started....

Thread 6 started....

Thread 7 started....

Thread 8 started....

Thread 9 started....

Thread 10 started....

Thread 10 ended.

Thread 9 ended.

Thread 8 ended.

Thread 7 ended.

Thread 6 ended.

Thread 5 ended.

Thread 4 ended.

Thread 3 ended.

Thread 2 ended.

Thread 1 ended.

即程序会根据按照正序启动10个线程,然后逆序结束线程。

5.将ThirdRunnable类改写,使其能够按照任意顺序结束;

下面是就是改写后的结果。

package https://www.360docs.net/doc/774494614.html,b2;

public class FourthRunnable implements Runnable{

//线程按照下面熟组元素的顺序依次结束。

private static int t[]={4,5,9,3,1,0,2,6,8,7};

private int id;

private static int stopid=0;

public FourthRunnable(int id){

this.id=id;

}

public static void main(String[] args) {

for (int i=0;i

(new Thread(new FourthRunnable(i))).start();

}

}

public void run(){

System.out.println("Thread "+id+" started....");

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

while (id!=t[stopid]){

Thread.yield();

}

System.out.println("Thread "+id+" ended.");

stopid++;

}

}

6.编写代码实现实验内容中的第3题。

四、调试分析

在调试线程程序的过程中,并干扰到其它应用程序的正常运行,后来经过仔细观察,发现是因为在线程的循环体当中没有调用sleep语句,从而导致线程不断地抢占CPU,从而影响其它程序的正常运行。

五、实验结果

按照指导书的步骤完成了第1题和第2题,同时编写程序完成了第3题,达到了所要求

的实验结果。第3题的源代码如下:

//环形队列

package https://www.360docs.net/doc/774494614.html,b2;

public class DataQuque {

final int MAXLENGTH=10;

byte[] data=new byte[MAXLENGTH];

int length;

int startpos;

int endpos;

public int read(){

int b;

if (length<2)

return -1;

else if(startpos==MAXLENGTH-2){

b=data[MAXLENGTH-2];

b=b<<8;

b|=data[MAXLENGTH-1];

startpos=0;

length-=2;

return b;

}else if(startpos==MAXLENGTH-1){

b=data[MAXLENGTH-1];

b=b<<8;

b|=data[0];

length-=2;

startpos=1;

return b;

}else{

b=data[startpos];

b=b<<8;

b|=data[startpos+1];

length-=2;

startpos+=2;

return b;

}

}

public boolean write(int b){

if (length==MAXLENGTH)

return false;

else if(endpos==MAXLENGTH-1){

data[MAXLENGTH-1]=(byte)b;

endpos=0;

length++;

return true;

}else{

data[endpos++]=(byte)b;

length++;

return true;

}

}

}

//读取线程

package https://www.360docs.net/doc/774494614.html,b2;

public class DataReader extends Thread {

boolean flag = true;

DataQuque dq;

int id;

public DataReader(DataQuque dq, int id) {

this.dq = dq;

this.id = id;

}

public void run() {

int b;

try {

Thread.sleep(1000*id);

} catch (InterruptedException e) {

e.printStackTrace();

}

while (flag) {

synchronized (dq) {

if ((b = dq.read()) == -1)

try {

dq.wait();

} catch (InterruptedException e1) {

e1.printStackTrace();

}

else {

System.out.println("read:" + b+" dq:"+dq.length);

System.out.flush();

dq.notifyAll();

}

}

}

}

public void stopThread() {

flag = false;

}

}

//写入线程

package https://www.360docs.net/doc/774494614.html,b2;

public class DataWriter extends Thread{

boolean flag = true;

DataQuque dq;

int id;

public DataWriter(DataQuque dq, int id) {

this.dq = dq;

this.id = id;

}

public void run() {

try {

Thread.sleep(1000*id);

} catch (InterruptedException e) {

e.printStackTrace();

}

while (flag) {

synchronized (dq) {

if (!dq.write(id)){

try {

dq.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}else{

dq.notifyAll();

System.out.println("write:"+id+" dq:"+dq.length);

System.out.flush();

}

}

}

}

public void stopThread() {

flag = false;

}

}

//控制类(程序入口)

package https://www.360docs.net/doc/774494614.html,b2;

public class DataController {

public static void main(String[] args) {

DataQuque dq=new DataQuque();

DataWriter dw1=new DataWriter(dq,1);

DataWriter dw2=new DataWriter(dq,2);

DataReader dr=new DataReader(dq,3);

dw1.start();

dw2.start();

dr.start();

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

e.printStackTrace();

}

dw1.stopThread();

dw2.stopThread();

dr.stopThread();

}

}

六、实验总结

通过本次实验,熟悉了Java中线程的创建有二个方法,特别是runnable 接口的练习。需要在创建线程时候的参数是runnable 类的对象。

七、课后练习

1.编写一个多线程程序,该程序主要完成以下工作:

(1)生成两个发送线程s1,s2和一个接收线程r;

(2)接收线程r每接收到M个来自于s1的数据和N个s2的数据后将它们分别求平均值后输出;

(3)这样的接收过程总共进行3次。

//接收线程

package thread.control;

import java.util.*;

public class DataReciever extends Thread{

ArrayList datalist=new ArrayList();

final int MAX=10; //最多只能有10个发送线程

int datanum[]=new int[MAX]; //每个发送者每次能够发送的数据数

int datalength[]=new int[MAX]; //每个发送者能够发送的数据总数

int datacount[]=new int[MAX]; //每个发送者目前已纪发送的数据数

int average[]=new int[MAX];

int senderId;

int size;

int total;

volatile int count;

public DataReciever(){

}

public int connect(int datasize,int maxlength){

datanum[senderId]=datasize;

datalength[senderId]=maxlength;

total+=maxlength;

size+=datasize;

int data[]=new int[datasize]; //该发送线程的数据存储数组

datalist.add(data);

return senderId++;

}

public void run(){

int printcount=0;

int tempcount;

while(true){

tempcount=count;//count在运行中有可能会被接收线程改变,所以这里将它赋值给一个临时变量,以防止因它在运行过程中被改变而造成程序产生错误。

if ((tempcount%size==0)&& (tempcount>0)) {

if (printcount!=tempcount){

printcount=tempcount;//注意位置

printResult();

resetSenders();

}

}

if (tempcount>=total) break;

}

}

public boolean setData(int id,int data){ //新增数据

if (datacount[id]==datanum[id])return false;

addData(id,data);

return true;

}

private void addData(int id,int data){

int temp[]=(int[])datalist.get(id);

temp[datacount[id]]=data;

datacount[id]++;

count++;

}

private void printResult(){ //打印结果

for (int i=0;i

int data[]=(int [])datalist.get(i);

System.out.println("\n\n Data form sender "+i+" : ");

for (int j=0;j

{ System.out.print(data[j]+" ");

average[i]+=data[j];

}

average[i]/=datanum[i];

System.out.println("\n Average : "+average[i]);

}

}

private void resetSenders(){ //清空数据存储数组,准备接收下一组数据。

for (int i=0;i

datacount[i]=0;

}

}

}

//发送线程

package thread.control;

import java.util.Random;

public class DataSender extends Thread{

DataReciever dr;

int id;

int datasize; //求平均所需的数据数(M或N)

int maxlength; //总共要发送的数据数(M*TIMES或N*TIMES)

int count;

public DataSender(DataReciever dr,int datasize,int maxlength) {

this.dr=dr;

this.datasize=datasize;

this.maxlength=maxlength;

id=dr.connect(datasize,maxlength);//与接收线程连接,让接收线程为本发送线程建立数据传送通道(标识,数据数组,每次发送的数据长度,所有数据数)}

public void run() {

while (count < maxlength) { //数据超过最大数则结束线程int data = 0xFF&generateData();//随机产生一个数据

while (!dr.setData(id, data)) //发送数据

Thread.yield();

System.out.print(""+id+".<"+data+">.");

count++;

}

}

private int generateData() {

Random r=new java.util.Random();

return r.nextInt();

}

}

//控制类(产生两个发送线程和一个接收线程。)

package thread.control;

public class DataMain {

public static void main(String[] args) {

final int TIMES=4;

final int M=3,N=5;

DataSender s1,s2;

DataReciever r=new DataReciever();

s1=new DataSender(r,M,M*TIMES);

s2=new DataSender(r,N,N*TIMES);

r.start();

s1.start();

s2.start();

}

}

2.编写一个多线程程序,模拟多个售票点联网出售火车票的场景,假设车票有10张,购票人有20人,售票点有3个,要求最终能够输出每张车票的票号、售出地点、乘客姓名。

//乘客类

package https://www.360docs.net/doc/774494614.html,b2.ex2;

public class Person {

public int personid;

public String name;

public Person(int personid){

this.personid=personid;

}

}

//火车票类

package https://www.360docs.net/doc/774494614.html,b2.ex2;

public class Ticket {

public int ticketno;

public String description;

public Ticket(int ticketno){

this.ticketno=ticketno;

}

}

//售票点类

package https://www.360docs.net/doc/774494614.html,b2.ex2;

import java.util.*;

public class Position extends Thread{

int positionid; //售票点标识

ArrayList personlist; //参加排队的乘客列表

ArrayList ticketlist; //所有的火车票列表

static boolean soldoutflag=false; //标记票是否售完

public Position(int positionid,ArrayList ticketlist){

this.positionid=positionid;

this.ticketlist=ticketlist;

personlist=new ArrayList();

}

public void addPerson(Person p){ //增加一个人排队

personlist.add(p);

}

public boolean sellTicket(Person p){ //售票

synchronized(ticketlist){

if (soldoutflag) return false;

Iterator it = ticketlist.iterator();

Ticket t=null;

if (it.hasNext())

t = (Ticket) it.next();

else {

System.out.println("Ticket is sold out.");

soldoutflag=true;

return false;

}

if (t != null) {

System.out.println("Ticket " + t.ticketno +

" is sold to person "+p.personid+

" at position "+positionid+".");

it.remove();

}

return true;

}

}

public void run(){

Iterator it=personlist.iterator();

Person p;

Random rnd = new Random();

while (it.hasNext()){ //按排队顺序售票

p=(Person)it.next();

if(!sellTicket(p))break;

it.remove();

try {

sleep(Math.abs(rnd.nextInt())%4000); //随机产生的每次售票过程所需的时间

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

//控制类

package https://www.360docs.net/doc/774494614.html,b2.ex2;

import java.util.*;

public class TicketController {

public static void main(String[] args) {

int i;

ArrayList ticketlist=new ArrayList();

ArrayList personlist=new ArrayList();

Ticket t;

Position pos[]=new Position[3];

Person p;

for (i=0;i<10;i++){

t=new Ticket(i);

ticketlist.add(t);

}

for (i=0;i<3;i++){

pos[i]=new Position(i,ticketlist);

}

for (i=0;i<20;i++){ //将20个乘客分散到3个售票点p=new Person(i);

personlist.add(p);

pos[i%3].addPerson(p);

}

for (i=0;i<3;i++){

pos[i].start();

}

}

}

进程管理实验报告

进程的控制 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()); }

实验二(1)进程同步

实验二(2)进程同步 一、实验目的 1、生产者-消费者问题是很经典很具有代表性的进程同步问题,计算机中的很多同步问题都可抽象为生产者-消费者问题,通过本实验的练习,希望能加深学生对进程同步问题的认识与理解。 2、熟悉VC的使用,培养和提高学生的分析问题、解决问题的能力。 二、实验内容及其要求 1.实验内容 以生产者/消费者模型为依据,创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。 2.实验要求 学习并理解生产者/消费者模型及其同步/互斥规则;设计程序,实现生产者/消费者进程(线程)的同步与互斥; 三、实验算法分析 1、实验程序的结构图(流程图); 2、数据结构及信号量定义的说明; (1) CreateThread ●功能——创建一个在调用进程的地址空间中执行的线程 ●格式 HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize,

LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParamiter, DWORD dwCreationFlags, Lpdword lpThread ); ●参数说明 lpThreadAttributes——指向一个LPSECURITY_ATTRIBUTES(新线程的安全性描述符)。dwStackSize——定义原始堆栈大小。 lpStartAddress——指向使用LPTHRAED_START_ROUTINE类型定义的函数。 lpParamiter——定义一个给进程传递参数的指针。 dwCreationFlags——定义控制线程创建的附加标志。 lpThread——保存线程标志符(32位) (2) CreateMutex ●功能——创建一个命名或匿名的互斥量对象 ●格式 HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName); bInitialOwner——指示当前线程是否马上拥有该互斥量(即马 ●参数说明 lpMutexAttributes——必须取值NULL。上加锁)。 lpName——互斥量名称。 (3) CreateSemaphore ●功能——创建一个命名或匿名的信号量对象 ●格式 HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName ); ●参数说明 lpSemaphoreAttributes——必须取值NULL。

实验2-2windows2000 线程同步

实验2 并发与调度 2.2 Windows 2000线程同步 (实验估计时间:120分钟) 背景知识 实验目的 工具/准备工作 实验内容与步骤 背景知识 Windows 2000提供的常用对象可分成三类:核心应用服务、线程同步和线程间通讯。其中,开发人员可以使用线程同步对象来协调线程和进程的工作,以使其共享信息并执行任务。此类对象包括互锁数据、临界段、事件、互斥体和信号等。 多线程编程中关键的一步是保护所有的共享资源,工具主要有互锁函数、临界段和互斥体等;另一个实质性部分是协调线程使其完成应用程序的任务,为此,可利用内核中的事件对象和信号。 在进程内或进程间实现线程同步的最方便的方法是使用事件对象,这一组内核对象允许一个线程对其受信状态进行直接控制 (见表4-1) 。 而互斥体则是另一个可命名且安全的内核对象,其主要目的是引导对共享资源的访问。拥有单一访问资源的线程创建互斥体,所有想要访问该资源的线程应该在实际执行操作之前获得互斥体,而在访问结束时立即释放互斥体,以允许下一个等待线程获得互斥体,然后接着进行下去。 与事件对象类似,互斥体容易创建、打开、使用并清除。利用CreateMutex() API 可创建互斥体,创建时还可以指定一个初始的拥有权标志,通过使用这个标志,只有当线程完成了资源的所有的初始化工作时,才允许创建线程释放互斥体。

为了获得互斥体,首先,想要访问调用的线程可使用OpenMutex() API来获得指向对象的句柄;然后,线程将这个句柄提供给一个等待函数。当内核将互斥体对象发送给等待线程时,就表明该线程获得了互斥体的拥有权。当线程获得拥有权时,线程控制了对共享资源的访问——必须设法尽快地放弃互斥体。放弃共享资源时需要在该对象上调用ReleaseMute() API。然后系统负责将互斥体拥有权传递给下一个等待着的线程(由到达时间决定顺序) 。 实验目的 在本实验中,通过对事件和互斥体对象的了解,来加深对Windows 2000线程同步的理解。 1) 回顾系统进程、线程的有关概念,加深对Windows 2000线程的理解。 2) 了解事件和互斥体对象。 3) 通过分析实验程序,了解管理事件对象的API。 4) 了解在进程中如何使用事件对象。 5) 了解在进程中如何使用互斥体对象。 6) 了解父进程创建子进程的程序设计方法。 工具/准备工作 在开始本实验之前,请回顾教科书的相关内容。 您需要做以下准备: 1) 一台运行Windows 2000 Professional操作系统的计算机。 2) 计算机中需安装Visual C++ 6.0专业版或企业版。 实验内容与步骤 1. 事件对象 2. 互斥体对象 1. 事件对象 清单2-1程序展示了如何在进程间使用事件。父进程启动时,利用CreateEvent() API创建一个命名的、可共享的事件和子进程,然后等待子进程向事件发出信号并终止父进程。在创建时,子进程通过OpenEvent() API打开事件对象,调用SetEvent() API使其转化为已接受信号状态。两个进程在发出信号之后几乎立即终止。 步骤1:登录进入Windows 2000 Professional。 步骤2:在“开始”菜单中单击“程序”-“Microsoft Visual Studio 6.0”–“Microsoft Visual C++ 6.0”命令,进入Visual C++窗口。

java多线程实验报告

java多线程实验报告 篇一:西北农林科技大学java多线程实验报告 实验7 多线程 1.实验目的 (1) 掌握Java多线程的概念和实现方法 (2) 掌握Java多线程的同步问题 2.实验内容 任务一:火车售票 假设有火车票1000张,创建10个线程模拟10个售票点,每个售票点100毫秒买一张票。打印出售票过程,注意使用synchronized确保同一张票只能卖出一次。程序运行结果见左图。 打开Eclipse Tickets.java public class Ticket extends Thread { int ticket =1000; String name =""; public void run(){ while(true){synchronized(name){ if(ticket "第" + Thread.currentThread().getName()+ "售票点卖出了第" + ticket-- + "张票"); } } } }} try{ } catch(InterruptedException e){ }

Thread.sleep(100); Test.java public class Test { } public static void main(String args[]){} Ticket t = new Ticket(); new Thread(t,"1").start(); new Thread(t,"2").start(); new Thread(t,"3").start(); new Thread(t,"4").start(); new Thread(t,"5").start(); new Thread(t,"6").start(); new Thread(t,"7").start(); new Thread(t,"8").start(); new Thread(t,"9").start(); new Thread(t,"10").start(); 任务二:银行存款 假设某家银行,它可接受顾客的汇款,每做一次汇款,便可计算出汇款的总额。现有两个顾客,每人都分3次,每次100元将钱到入。试编写一个程序,模拟实际作业。 程序如下: classCBank { private static int sum=0; public static void add(int n){ inttmp=sum; tmp=tmp+n;// 累加汇款总额 try{ Thread.sleep((int)(10000*Math.random())); //

os实验二 进程同步

实验二:进程同步 一.实验目的 (1)掌握基本的同步算法,理解生产者消费者模型。 (2)学习使用Windows XP中基本的同步对象,掌握相关API的使用方法。 (3)了解Windows XP中多线程的并发执行机制,实现进程的同步与互斥。 二.实验属性 该实验为设计性实验。 三.实验仪器设备及器材 普通PC386以上微机 四.实验要求 本实验要求2学时完成。 本实验要求完成如下任务: (1)以生产者/消费者模型为依据,在Windows XP环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。 学习并理解生产者/消费者模型及其同步/互斥规则; 学习了解Windows同步对象及其特性; 熟悉实验环境,掌握相关API的使用方法; 设计程序,实现生产者/消费者进程(线程)的同步与互斥。 (2)扩展任务2选1: 1>利用信号量机制,写出不会发生死锁的解决哲学家进程(线程)。 最多允许4个同时进餐;奇:先左后右偶:先右后左。 2>利用信号量机制,写出不会发生死锁的读者写者进程(线程)。五:实验内容: 利用至多同时允许4位哲学家同时去拿左边筷子的方法解决进餐死锁的问题。 实验详细设计:流程图:

程序首先创建一个线程参数结构体 struct ThreadInfo { int serial; double delay; }; 设置最多同时去拿筷子的人数#define MAX_BUFFER_NUM 4 设置一个信号量数组用来表示五位哲学家的左右边的筷子HANDLE chopstick [5]; 设置同时去拿筷子的人数的信号量HANDLE People; 设置一个互斥信号量HANDLE h_mutex; 在main()函数中,首先创建信号量: for (int i=0;i<5;i++) { chopstick[i]=CreateSemaphore(NULL,n_Buffer_or_Critical,n_Buffer_or_Criti cal,"chopstick"+i); } People=CreateSemaphore(NULL,MAX_BUFFER_NUM,MAX_BUFFER _NUM,"People");

进程的同步实验报告汇总

操作系统 实验报告 哈尔滨工程大学 计算机科学与技术学院

一、实验概述 1. 实验名称 进程的同步 2. 实验目的 ⑴使用EOS的信号量,编程解决生产者 消费者问题,理解进程同步的意义。 ⑵调试跟踪EOS信号量的工作过程,理解进程同步的原理。 ⑶修改EOS的信号量算法,使之支持等待超时唤醒功能(有限等待),加深理解进程同步的原理。 3. 实验类型 验证+设计 4. 实验内容 ⑴准备实验 ⑵使用EOS的信号量解决生产者-消费者问题 ⑶调试EOS信号量的工作过程 ①创建信号量 ②等待释放信号量 ③等待信号量(不阻塞) ④释放信号量(不唤醒) ⑤等待信号量(阻塞) ⑥释放信号量(唤醒) ⑷修改EOS的信号量算法 二、实验环境 WindowsXP + EOS集成实验环境 三、实验过程 1. 设计思路和流程图

图4-1.整体试验流程图

图4-2.Main 函数流程图、生产者消费、消费者流程图 2. 算法实现 3. 需要解决的问题及解答 (1). 思考在ps/semaphore.c 文件内的PsWaitForSemaphore 和PsReleaseSemaphore 函数中,为什么要使用原子操作?

答:在执行等待信号量和释放信号量的时候,是不允许cpu响应外部中断的,如果此时cpu响应了外部中断,会产生不可预料的结果,无法正常完成原子操作。 (2). 绘制ps/semaphore.c文件内PsWaitForSemaphore和PsReleaseSemaphore函数的流程图。 (3).P143生产者在生产了13号产品后本来要继续生产14号产品,可此时生产者为什么必须等待消费者消费了4号产品后,才能生产14号产品呢?生产者和消费者是怎样使用同步对象来实现该同步过程的呢? 答:这是因为临界资源的限制。临界资源就像产品仓库,只有“产品仓库”空闲生产者才能生产东西,有权向里面放东西。所以它必须等到消费者,取走产品,“产品空间”(临界资源)空闲时,才继续生产14号产品。 (4). 根据本实验3.3.2节中设置断点和调试的方法,自己设计一个类似的调试方案来验证消费者线程在消费24号产品时会被阻塞,直到生产者线程生产了24号产品后,消费者线程才被唤醒并继续执行的过程。 答:可以按照下面的步骤进行调试 (1) 删除所有的断点。 (2) 按F5启动调试。OS Lab会首先弹出一个调试异常对话框。 (3) 在调试异常对话框中选择“是”,调试会中断。 (4) 在Consumer函数中等待Full信号量的代码行(第173行)WaitForSingleObject(FullSemaphoreHandle, INFINITE); 添加一个断点。 (5) 在“断点”窗口(按Alt+F9打开)中此断点的名称上点击右键。 (6) 在弹出的快捷菜单中选择“条件”。 (7) 在“断点条件”对话框(按F1获得帮助)的表达式编辑框中,输入表达式“i == 24”。 (8) 点击“断点条件”对话框中的“确定”按钮。 (9) 按F5继续调试。只有当消费者线程尝试消费24号产品时才会在该条件断点处中断。 4. 主要数据结构、实现代码及其说明 修改PsWaitForSemaphore函数 if (Semaphore->Count>0){ Semaphore->Count--; flag=STATUS_SUCCESS; }//如果信号量大于零,说明尚有资源,可以为线程分配 else flag=PspWait(&Semaphore->WaitListHead, Milliseconds); KeEnableInterrupts(IntState); // 原子操作完成,恢复中断。 return flag; }//否则,说明资源数量不够,不能再为线程分配资源,因此要使线程等待 修改PsReleaseSemaphore函数 if (Semaphore->Count + ReleaseCount > Semaphore->MaximumCount) {

Java多线程实验报告

实验报告 课程名称: Java语言程序设计 姓名: 学号: 班级: 数学与计算机科学学院

数学与计算机科学学院实验报告实验名称:多线程 指导教师:日期:

if (isPrime) count++; } System.out.println(st + "~" + en + "之间共有" + count + "个质数"); } public static void main(String[] args) { UseThread thread1 = new UseThread(2, 1000); UseThread thread2 = new UseThread(1000, 2000); thread1.start(); thread2.start(); } } 第2题代码: public class Experiment14_2 { public static void main(String[] args) { MyThread t1 = new MyThread("T1"); MyThread t2 = new MyThread("T2"); t1.start(); t2.start(); System.out.println("活动线程数:" + Thread.activeCount()); System.out.println("main()运行完毕"); } } class MyThread extends Thread { public MyThread(String s) { super(s); } public void run() { for (int i = 1; i <= 3; i++) { System.out.println(getName() + "第" + i + "次运行"); try { sleep((int) (Math.random() * 100)); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(getName() + "结束"); } }

山东大学操作系统实验报告4进程同步实验

山东大学操作系统实验报告4进程同步实验

计算机科学与技术学院实验报告 实验题目:实验四、进程同步实验学号: 日期:20120409 班级:计基地12 姓名: 实验目的: 加深对并发协作进程同步与互斥概念的理解,观察和体验并发进程同步与互斥 操作的效果,分析与研究经典进程同步与互斥问题的实际解决方案。了解 Linux 系统中 IPC 进程同步工具的用法,练习并发协作进程的同步与互斥操作的编程与调试技术。 实验内容: 抽烟者问题。假设一个系统中有三个抽烟者进程,每个抽烟者不断地卷烟并抽烟。抽烟者卷起并抽掉一颗烟需要有三种材料:烟草、纸和胶水。一个抽烟者有烟草,一个有纸,另一个有胶水。系统中还有两个供应者进程,它们无限地供应所有三种材料,但每次仅轮流提供三种材料中的两种。得到缺失的两种材料的抽烟者在卷起并抽掉一颗烟后会发信号通知供应者,让它继续提供另外的两种材料。这一过程重复进行。请用以上介绍的 IPC 同步机制编程,实现该问题要求的功能。 硬件环境: 处理器:Intel? Core?i3-2350M CPU @ 2.30GHz ×4 图形:Intel? Sandybridge Mobile x86/MMX/SSE2 内存:4G 操作系统:32位 磁盘:20.1 GB 软件环境: ubuntu13.04 实验步骤: (1)新建定义了producer和consumer共用的IPC函数原型和变量的ipc.h文件。

(2)新建ipc.c文件,编写producer和consumer 共用的IPC的具体相应函数。 (3)新建Producer文件,首先定义producer 的一些行为,利用系统调用,建立共享内存区域,设定其长度并获取共享内存的首地址。然后设定生产者互斥与同步的信号灯,并为他们设置相应的初值。当有生产者进程在运行而其他生产者请求时,相应的信号灯就会阻止他,当共享内存区域已满时,信号等也会提示生产者不能再往共享内存中放入内容。 (4)新建Consumer文件,定义consumer的一些行为,利用系统调用来创建共享内存区域,并设定他的长度并获取共享内存的首地址。然后设定消费者互斥与同步的信号灯,并为他们设置相应的初值。当有消费进程在运行而其他消费者请求时,相应的信号灯就会阻止它,当共享内存区域已空时,信号等也会提示生产者不能再从共享内存中取出相应的内容。 运行的消费者应该与相应的生产者对应起来,只有这样运行结果才会正确。

实验二进程同步

实验二进程同步演示 一、实验目的 ?深入掌握进程同步机制——信号量的应用; ?掌握Windows编程中信号量机制的使用方法; ?可进行简单的信号量应用编程。 二、实验工具 Windows系统+ VC++ 6.0 三、实验内容 1、复习教材上信号量机制的定义与应用,复习经典进程同步问题——生产者消费者问题及其同步方案; 2、验证后附的参考代码pc.cpp(生产者消费者问题),掌握Windows系统中信号量的定义与使用方法; 注意: (1)代码中生产者和消费者所做的工作用过程Producer和Consumer描述,并通过创建线程的方法创建3个生产者线程和1个消费者线程,具体创建方法:CreateThread(NULL,0,Producer,NULL,0,&producerID[i]);其中第3个参数就是指定该线程所做的工作为过程Producer; (2)问题中设置了三个信号量g_hMutex(用于互斥访问临界区buffer)、 g_hFullSemaphore、g_hEmptySemaphore(用于控制同步的资源信号量),先声明,再定义,最后使用。互斥信号量和资源信号量的定义方法不同: g_hMutex = CreateMutex(NULL,FALSE,NULL); 互斥信号量最开始没有指定针对那个资源g_hFullSemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL); 其中第2和3个参数为信号量的初始值和最大值 信号量的使用方法:WaitForSingleObject为信号量的P操作,每对一个信号量执行该操作,则信号量值减1,并判断减1后值是否仍大于等于0,如是则该操作成功,否则进程阻塞;ReleaseSemaphore为信号量的V操作,每执行一次将该信号量的值加1,并起到唤醒作用。如: WaitForSingleObject(g_hFullSemaphore,INFINITE); … ReleaseSemaphore(g_hEmptySemaphore,1,NULL);

多线程同步操作多个窗口

多线程同步操作多个窗口 RunApp "notepad.exe" RunApp "notepad.exe" RunApp "notepad.exe" Delay 2000 Dimenv temp_Hwnd temp_Hwnd = 0 Dim str, arr, i str = Plugin.Window.Search("无标题- 记事本") arr = Split(str, "|") For i = 0 To UBound(arr) - 1 temp_Hwnd = Plugin.Window.FindEx(arr(i), 0, "Edit", 0) BeginThread WriteString While temp_Hwnd <> 0'判断多线程已经启动完毕,继续循环下一个。 Delay 500 Wend Next EndScript Function WriteString() Dim str, Hwnd Hwnd = temp_Hwnd temp_Hwnd = 0 Do str = WaitKey If Hwnd <> Plugin.Window.GetKeyFocusWnd Then Call Plugin.Bkgnd.KeyPress(Hwnd, str) End If Loop End Function 多线程多开窗口同步执行与子线程间的数值如何传递: 1.Dimenv IsThread, i 2.Dim arr_Thread() 3.For i = 0 To 2 4. IsThread = False'未启动线程 5. Redim Preserve arr_Thread(i) 6. arr_Thread(i) = BeginThread(EnterThread) 7. While IsThread = False'未启动成功,等待中 8. Delay 500 9. Wend 10. '跳出循环说明 IsThread = True,已经执行到了,循环继续启动下一个 11.Next

进程(线程)的同步与互斥实验报告

操作系统实验报告 课程名称操作系统实验名称进程(线程)的同步与互斥成绩 学生姓名作业君专业软件工程班级、学号 同组者姓名无实验日期2020 一、实验题目:进程(线程)的同步与互斥 二、实验目的: 自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的PCB内容、组织的变化,理解进程与其PCB间的一一对应关系。1.掌握基本的同步与互斥算法,理解生产者消费者模型。 2.学习使用Windows中基本的同步对象,掌握相关API的使用方法。 3.了解Windows中多线程的并发执行机制,实现进程的同步与互斥 三、实验内容与要求: 1.实验内容 以生产者/消费者模型为依据,在Windows 环境下创建一个控制台进程,在该进程中创建n个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。 2.实验要求 学习并理解生产者/消费者模型及其同步/互斥规则; 学习了解Windows同步对象及其特性; 熟悉实验环境,掌握相关API的使用方法; 设计程序,实现生产者/消费者进程(线程)的同步与互斥; 四、算法描述(含数据结构定义)或流程图 #include #include #include #include #include #include using namespace std;

#define MAX_THREAD_NUM 64 //最大线程数 #define INTE_PER_SEC 1000 //延迟时间的毫秒值 const int SIZE_OF_BUFFER = 10; //缓冲区长度 int ProductID = 0; //产品号 int ConsumeID = 0; //将被消耗的产品号 int in = 0; //产品进缓冲区时的缓冲区下标 int out = 0; //产品出缓冲区时的缓冲区下标 bool running = true; //判断程序能否继续执行的逻辑值 int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列 HANDLE g_hMutex; //公有信号量,用于线程间的互斥HANDLE g_hFullSemaphore; //生产者的私有信号量,当缓冲区满时迫使生产者等待 HANDLE g_hEmptySemaphore; //消费者的私有信号量,当缓冲区空时迫使消费者等待 //定义一个结构体用于存储线程的信息 struct ThreadInfo { int serial; //线程号 char entity; //线程类别(生产者或消费者) double delay; //等待时间 double persist; //操作时间 }; //生产者 void Producer(void* p) { //定义变量用于存储当前线程的信息 DWORD m_delay; DWORD m_persist; int m_serial; //从参数中获得信息 m_serial = ((ThreadInfo*)(p))->serial; m_delay = (DWORD)(((ThreadInfo*)(p))->delay * INTE_PER_SEC); m_persist = (DWORD)(((ThreadInfo*)(p))->persist * INTE_PER_SEC); while (running) { //P操作 cout << "生产者线程 " << m_serial << " 请求生产." << endl; WaitForSingleObject(g_hEmptySemaphore, INFINITE);

线程实验报告

线 程实验报告 黄澄宇320070911241 1.分析 (1)问题阐述,描述。 运用线程的方法设计一个ftp面向客户\服务器的网络应用程序,主要包括服务器端和客户端两方面的工作。 (2)问题分析。 针对问题要求,应该能够实现客户端和服务器端的功能。其中服务器端主要对客户端进行监听。客户端向服务器端进行提出请求。 (3)寻找揭发。 TCP\IP服务器端应用程序都是通过JA V A语言中提供的SeverSocket和Socket两个有关网络的类来实现。 SeverSocket类除了建立一个Sever之外,还通过accept()方法提供了随时监听客户端连接请求的功能。 2.设计。 在服务器端指定一个用来等待连接的端口号,在客户端规定一个主机和端口号,从而在客户端和服务器端创建Socket\ServerSocket实例。

现在服务器端生成一个ServerSocket实例的对象,随时监听客户端的连接请求。 当客户端需要连接时,相应的要生成一个Socket实例的对象,并发出连接请求,其在host参数指明该主机名,port参数指明端口号。 服务器端通过accept()方法接收到客户端的请求后,开辟一个接口与之进行连接,利用输入输出流,按照一定的协议对Socket 进行读写操作。 关闭输入输出流和Socket。 3.实现。 //FTPServer.java import https://www.360docs.net/doc/774494614.html,.*; import java.io.*; import java.util.*; public class FTPServer { public static void main(String args[]) throws Exception { ServerSocket soc=new ServerSocket(5127); System.out.println("FTP Server Started on Port Number "); while(true) {

4:一个经典的多线程同步问题汇总

一个经典的多线程同步问题 程序描述: 主线程启动10个子线程并将表示子线程序号的变量地址作为参数传递给子线程。子线程接收参数 -> sleep(50) -> 全局变量++ -> sleep(0) -> 输出参数和全局变量。 要求: 1.子线程输出的线程序号不能重复。 2.全局变量的输出必须递增。 下面画了个简单的示意图: 分析下这个问题的考察点,主要考察点有二个: 1.主线程创建子线程并传入一个指向变量地址的指针作参数,由于线程启动须要花费一定的时间,所以在子线程根据这个指针访问并保存数据前,主线程应等待子线程保存完毕后才能改动该参数并启动下一个线程。这涉及到主线程与子线程之间的同步。 2.子线程之间会互斥的改动和输出全局变量。要求全局变量的输出必须递增。这涉及到各子线程间的互斥。 下面列出这个程序的基本框架,可以在此代码基础上进行修改和验证。 //经典线程同步互斥问题 #include #include #include long g_nNum; //全局资源 unsigned int__stdcall Fun(void *pPM); //线程函数 const int THREAD_NUM = 10; //子线程个数 int main() { g_nNum = 0;

HANDLE handle[THREAD_NUM]; int i = 0; while (i < THREAD_NUM) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL); i++;//等子线程接收到参数时主线程可能改变了这个i的值} //保证子线程已全部运行结束 WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE); return 0; } unsigned int__stdcall Fun(void *pPM) { //由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来int nThreadNum = *(int *)pPM; //子线程获取参数 Sleep(50);//some work should to do g_nNum++; //处理全局资源 Sleep(0);//some work should to do printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum); return 0; } 运行结果:

实验四 同步与互斥 Linux实验报告

实验四同步与互斥 【实验目的和要求】 1、掌握进程(线程)的同步与互斥。 2、掌握生产者消费者问题的实现方法。 3、掌握多线程编程方法。 【实验内容】 实现生产者消费者问题 1、有一个仓库,生产者负责生产产品,并放入仓库,消费者会从仓库中拿走产品(消费)。 2、仓库中每次只能入一个(生产者或消费者)。 3、仓库中可存放产品的数量最多10个,当仓库放满时,生产者不能再放入产品。 4、当仓库空时,消费者不能从中取出产品。 5、生产、消费速度不同。 【实验原理】 1、信号量mutex提供对缓冲池访问的互斥要求并初始化为1,信号量empty和 full分别用来表示空缓冲项和满缓冲项的个数,信号量empty初始化为n,信号量full初始化为0。 2、定义如下结构及数据: 定义缓冲区内的数据类型:typedef int buffer_item; 缓冲区:buffer_item buffer[BUFFER_SIZE];

对缓冲区操作的变量:int in,out; 信号量mutex提供了对缓冲池访问的互斥要求:pthread_mutex_t mutex; 信号量empty和full分别表示空缓冲顶和满缓冲顶的个数:sem_t empty,full; 可以设定生产者的生产速度及消费者的消费速度:int pro_speed,con_speed; 对缓冲区操作的自增函数:#define inc(k) if(k < BUFFER_SIZE) k = k+1;else k=0 3、并定义了如下实现问题的函数模块: 将生产的产品放入缓冲区: int insert_item(buffer_item item) 从缓冲区内移走一个产品: int remove_item(buffer_item *item) 生产者进程:void *producer(void *param) 消费者进程:void *consumer(void *param) 生产者结构进程消费者结构进程 【程序代码】 //sx.c #include

JAVA线程程序设计(小时钟)实验报告(附完整代码)

线程程序设计 一、课题内容和要求 内容:设计和编写一个编写一个指针式时钟程序,应用线程实现时钟的走动。 要求:本实验旨在通过实验,培养学生将JAVA 线程的相关知识点(包括线程调度,线程同步等)有机结合并加以综合应用,在实验中设计多线程程序的能力。 二、设计思路分析 class Clock:一个指针式时钟的主类 class Layout: 添加窗口和时钟组件 class ClockPaint:定义时钟组件 三、概要设计 public class Clock extends JFrame { public static void main(String[] s) ; } class Layout extends JFrame { public Layout(); } class ClockPaint extends JPanel implements Runnable { int x, y, r; int h, m, s; double rad = Math.PI / 180; public ClockPaint(int x, int y, int r); public void paint(Graphics g); public void run(); } 时钟的绘制:

运行时钟: 四、详细设计 import java.awt.*; import javax.swing.*; import java.util.*; public class Clock extends JFrame { public static void main(String[] s) { new Layout(); } } class Layout extends JFrame {// 添加窗口和时钟组件public Layout() { ClockPaint cp = new ClockPaint(20, 20, 70); add(cp);

进程同步实验报告

实验三进程的同步 一、实验目的 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)创建两个子进程:

用多线程同步方法解决生产者-消费者问题(操作系统课设)

. 题目用多线程同步方法解决生产者-消费 者问题(Producer-Consumer Problem) 学院计算机科学与技术学院 专业软件工程 班级 姓名 指导教师 年月日

目录 目录 (1) 课程设计任务书 (2) 正文 (2) 1.设计目的与要求 (2) 1.1设计目的 (2) 1.2设计要求 (2) 2.设计思想及系统平台 (2) 2.1设计思想 (2) 2.2系统平台及使用语言 (2) 3.详细算法描述 (3) 4.源程序清单 (5) 5.运行结果与运行情况 (10) 6.调试过程 (15) 7.总结 (15) 本科生课程设计成绩评定表 (16)

课程设计任务书 学生姓名:专业班级: 指导教师:工作单位:计算机科学与技术学院 题目: 用多线程同步方法解决生产者-消费者问题 (Producer-Consumer Problem) 初始条件: 1.操作系统:Linux 2.程序设计语言:C语言 3.有界缓冲区内设有20个存储单元,其初值为0。放入/取出的数据项按增序设定为1-20这20个整型数。 要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要 求) 1.技术要求: 1)为每个生产者/消费者产生一个线程,设计正确的同步算法 2)每个生产者和消费者对有界缓冲区进行操作后,即时显示有界缓冲区的当前全部内容、当前指针位置和生产者/消费者线程的自定义标识符。 3)生产者和消费者各有两个以上。 4)多个生产者或多个消费者之间须共享对缓冲区进行操作的函数代码。 2.设计说明书内容要求: 1)设计题目与要求 2)总的设计思想及系统平台、语言、工具等。 3)数据结构与模块说明(功能与流程图) 4)给出用户名、源程序名、目标程序名和源程序及其运行结果。(要注明存储各个程序及其运行结果的主机IP地址和目录。) 5)运行结果与运行情况 (提示: (1)有界缓冲区可用数组实现。 (2)编译命令可用:cc -lpthread -o 目标文件名源文件名 (3)多线程编程方法参见附件。) 3. 调试报告: 1)调试记录 2)自我评析和总结 上机时间安排: 18周一~ 五 08:0 - 12:00 指导教师签名:年月日

相关文档
最新文档