线程实验报告
进程(线程)同步和互斥实验报告
![进程(线程)同步和互斥实验报告](https://img.taocdn.com/s3/m/75ce0b60ec3a87c24128c4ac.png)
进程(线程)同步和互斥实验报告操作系统实验报告课程名称操作系统实验名称进程(线程)的同步与互斥成绩学生姓名作业君专业软件工程班级、学号同组者姓名无实验日期2021一、实验题目: : 进程(线程)的同步与互斥二、实验目的:自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的 PCB 内容、组织的变化,理解进程与其 PCB 间的一一对应关系。
1.掌握基本的同步与互斥算法,理解生产者消费者模型。
2.学习使用 Windows 中基本的同步对象,掌握相关 API 的使用方法。
3.了解 Windows 中多线程的并发执行机制,实现进程的同步与互斥三、实验内容与要求:1.实验内容以生产者/消费者模型为依据,在 Windows 环境下创建一个控制台进程,在该进程中创建 n 个线程模拟生产者和消费者,实现进程(线程)的同步与互斥。
2.实验要求学习并理解生产者/消费者模型及其同步/互斥规则;学习了解 Windows 同步对象及其特性;熟悉实验环境,掌握相关 API 的使用方法;设计程序,实现生产者/消费者进程(线程)的同步与互斥;四、算法描述(含数据结构定义)或流程图#include <Windows.h> #include <iostream> #include<stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> using namespace std;#define MA__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;//判断程序能否继续执行的逻辑值 intg_buffer[SIZE_OF_BUFFER];//缓冲区是个循环队列 HANDLE g_hMute_;//公有信号量,用于线程间的互斥 HANDLEg_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);cout << “生产者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_, INFINITE);Sleep(m_delay);//延迟等待//生产一个产品cout << “生产者线程”<< m_serial << “ 生产” << ++ProductID << “ 号产品成功.” << endl;cout << “生产者线程” << m_serial << “ 请求将产品” << ProductID << “ 投入缓冲区.” << endl;//把新生产的产品放入缓冲区g_buffer[in] = ProductID;in = (in +1)%SIZE_OF_BUFFER;Sleep(m_persist);//操作等待cout << “生产者线程” << m_serial << “ 将产品” << ProductID << “ 投入缓冲区中成功.” << endl;//输出缓冲区当前的状态cout << “____________________________” << endl<< “\n 当前缓冲区情况如图(■代表已有产品,□代表没有产品):” << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hFullSemaphore, 1, NULL);} }//消费者 void Consumer(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_hFullSemaphore, INFINITE);cout << “消费者线程” << m_serial << “ 请求独占缓冲区.” << endl;WaitForSingleObject(g_hMute_,INFINITE);Sleep(m_delay); //延迟等待//从缓冲区中取出一个产品cout << “消费者线程” << m_serial << “ 请求取出一个产品.” << endl;ConsumeID = g_buffer[out];g_buffer[out] = 0;out = (out + 1) % SIZE_OF_BUFFER;cout << “消费者线程” << m_serial << “ 取出产品” << ConsumeID << “ 成功.” << endl;//消耗一个产品cout << “消费者线程” << m_serial << “ 开始消费消费产品” << ConsumeID << “.” << endl;Sleep(m_persist);cout << “消费者线程” << m_serial << “ 消费产品” << ConsumeID << “ 成功.” << endl;//输出缓冲区当前的状态cout << “____________________________” << endl<< “\n 当前缓冲区情况如图:” << endl;for (int i = 0;i < SIZE_OF_BUFFER;++i){if (g_buffer[i] != 0)cout << “■”;elsecout << “□”;}cout << “\n\n____________________________\n” << endl;//V 操作ReleaseMute_(g_hMute_);ReleaseSemaphore(g_hEmptySemaphore, 1, NULL);} }void prod_cons {//创建互斥信号量g_hMute_ = CreateMute_(NULL, FALSE, NULL);//创建同步信号量g_hEmptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER, SIZE_OF_BUFFER, NULL);g_hFullSemaphore = CreateSemaphore(NULL, 0,SIZE_OF_BUFFER, NULL);srand((unsigned)time(NULL));//以时间函数为种子const unsigned short THREADS_COUNT = rand % 5 + 5; //总的线程数(随机生成)//线程对象的数组HANDLE hThreads[MA__THREAD_NUM];ThreadInfo thread_info[MA__THREAD_NUM];DWORD thread_ID; //线程 IDint num = 0;//临时变量,用于循环语句cout << “系统开始模拟,并自动生成模拟数据...” << endl;system(“pause”); //暂停确认开始执行cout << “线程总数:” << THREADS_COUNT << endl;//循环随机生成各个线程的信息while (num != THREADS_COUNT){thread_info[num].serial = num + 1;if (rand % 2 == 1)thread_info[num].entity = "P";elsethread_info[num].entity = "C";thread_info[num].delay = rand % 5 + 1;thread_info[num].persist = rand % 6 + 2;num++;}cout << “\n 系统生成数据结束,模拟数据如下:” << endl<< “线程号线程类别延迟时间操作时间” << endl;for (int _ = 0;_ < THREADS_COUNT;_++)cout << “” << thread_info[_].serial << “\t”<< “” << thread_info[_].entity << “\t”<< “” << thread_info[_].delay << “\t\t”<< “” << thread_info[_].persist << endl;cout << “\n\n==================生产者-消费者开始==================\n” << endl;//创建线程for (int i = 0;i < THREADS_COUNT;i++){//创建生产者线程if (thread_info[i].entity == "P")hThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Producer), ;thread_info[i], 0, ;thread_ID);//创建消费者线程elsehThreads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(Consumer), ;thread_info[i], 0, ;thread_ID);}while (running){if (getchar){//按回车后终止程序运行running = false;}}cout << “系统模拟结束...” << endl; } int main {cout << “\n==================生产者-消费者模拟==================\n” << endl;prod_cons; }五、实验过程1、记录生产者和消费者的同步执行过程。
线程实验报告
![线程实验报告](https://img.taocdn.com/s3/m/cb8d31143d1ec5da50e2524de518964bcf84d298.png)
线程实验报告线程实验报告引言:线程是计算机科学中的一个重要概念,它是操作系统能够进行运算调度的最小单位。
线程的使用能够提高程序的并发性和响应性,使得程序能够更高效地利用计算机资源。
本次实验旨在通过编写一个简单的多线程程序,来探究线程的工作原理和应用。
实验目的:1. 了解线程的基本概念和特点;2. 掌握线程的创建、同步和销毁方法;3. 理解多线程编程的优势和挑战。
实验过程:1. 创建线程在实验开始时,我们首先需要创建线程。
在C++中,可以使用pthread库来实现。
通过调用pthread_create函数,我们可以创建一个新的线程,并将其与指定的函数进行绑定。
在实验中,我们创建了两个线程,分别执行不同的任务。
2. 线程同步在多线程编程中,线程之间的同步是一个重要的问题。
为了避免竞态条件和资源争用,我们需要使用互斥锁和条件变量等同步机制。
在本次实验中,我们使用了互斥锁来保护共享资源的访问,以及条件变量来实现线程之间的通信。
3. 线程销毁线程的销毁是一个关键的步骤。
在实验中,我们使用了pthread_join函数来等待线程的结束,并回收线程的资源。
这样可以确保线程的正确退出,避免资源泄漏和程序崩溃。
实验结果:通过实验,我们发现多线程编程具有以下优势:1. 提高程序的并发性:通过并行执行多个任务,可以提高程序的运行效率,减少等待时间。
2. 增强程序的响应性:多线程可以使程序具有更好的交互性,用户可以在任务执行的同时进行其他操作。
3. 充分利用计算机资源:多线程能够充分利用多核处理器的计算能力,提高系统的整体性能。
然而,多线程编程也存在一些挑战:1. 竞态条件:当多个线程同时访问共享资源时,可能会导致数据的不一致性和程序的错误。
2. 死锁和饥饿:线程之间的同步问题可能导致死锁和饥饿现象,使得程序无法正常执行。
3. 调试困难:多线程程序的调试比单线程程序更加困难,需要仔细分析线程之间的交互关系。
结论:通过本次实验,我们深入了解了线程的工作原理和应用。
多线程通信实验报告(3篇)
![多线程通信实验报告(3篇)](https://img.taocdn.com/s3/m/e50c7ed8c67da26925c52cc58bd63186bdeb9263.png)
第1篇一、实验目的1. 理解多线程的概念和原理。
2. 掌握多线程间的通信方法,如共享内存、消息队列、信号量等。
3. 通过实验加深对多线程编程的理解,提高编程能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验内容1. 创建多线程2. 线程同步与互斥3. 线程间通信四、实验步骤1. 创建多线程(1)使用std::thread创建线程对象。
(2)在线程函数中定义线程要执行的任务。
(3)启动线程。
2. 线程同步与互斥(1)使用std::mutex互斥锁保护共享资源。
(2)使用std::lock_guard自动管理互斥锁。
(3)使用std::unique_lock手动管理互斥锁。
3. 线程间通信(1)使用共享内存a. 使用std::shared_mutex保护共享内存。
b. 使用std::lock_guard或std::unique_lock自动管理互斥锁。
c. 在线程函数中读取和写入共享内存。
(2)使用消息队列a. 使用std::queue创建消息队列。
b. 使用std::mutex保护消息队列。
c. 在生产者线程中添加消息到队列。
d. 在消费者线程中从队列中读取消息。
(3)使用信号量a. 使用std::semaphore创建信号量。
b. 在生产者线程中调用sem_post()增加信号量。
c. 在消费者线程中调用sem_wait()等待信号量。
五、实验代码```cppinclude <iostream>include <thread>include <mutex>include <queue>include <semaphore>std::mutex mtx;std::queue<int> q;std::semaphore sem(0);void producer() {for (int i = 0; i < 10; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::lock_guard<std::mutex> lock(mtx);q.push(i);std::cout << "Produced: " << i << std::endl;sem.post();}}void consumer() {while (true) {sem.wait();std::lock_guard<std::mutex> lock(mtx);int value = q.front();q.pop();std::cout << "Consumed: " << value << std::endl;}}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;}```六、实验结果与分析1. 创建多线程成功,线程函数执行任务。
多线程程序实验报告(3篇)
![多线程程序实验报告(3篇)](https://img.taocdn.com/s3/m/cb15f73576232f60ddccda38376baf1ffc4fe3b0.png)
第1篇一、实验目的1. 理解多线程的概念和作用。
2. 掌握多线程的创建、同步和通信方法。
3. 熟悉Java中多线程的实现方式。
4. 提高程序设计能力和实际应用能力。
二、实验环境1. 操作系统:Windows 102. 开发工具:IntelliJ IDEA3. 编程语言:Java三、实验内容本次实验主要完成以下任务:1. 创建多线程程序,实现两个线程分别执行不同的任务。
2. 使用同步方法实现线程间的同步。
3. 使用线程通信机制实现线程间的协作。
四、实验步骤1. 创建两个线程类,分别为Thread1和Thread2。
```javapublic class Thread1 extends Thread {@Overridepublic void run() {// 执行Thread1的任务for (int i = 0; i < 10; i++) {System.out.println("Thread1: " + i);}}}public class Thread2 extends Thread {@Overridepublic void run() {// 执行Thread2的任务for (int i = 0; i < 10; i++) {System.out.println("Thread2: " + i);}}}```2. 创建一个主类,在主类中创建两个线程对象,并启动它们。
```javapublic class Main {public static void main(String[] args) {Thread thread1 = new Thread1();Thread thread2 = new Thread2();thread1.start();thread2.start();}```3. 使用同步方法实现线程间的同步。
```javapublic class SynchronizedThread extends Thread {private static int count = 0;@Overridepublic void run() {for (int i = 0; i < 10; i++) {synchronized (SynchronizedThread.class) {count++;System.out.println(Thread.currentThread().getName() + ": " + count);}}}}public class Main {public static void main(String[] args) {Thread thread1 = new SynchronizedThread();Thread thread2 = new SynchronizedThread();thread1.start();thread2.start();}```4. 使用线程通信机制实现线程间的协作。
线程实例实验报告总结
![线程实例实验报告总结](https://img.taocdn.com/s3/m/8db1056cbb1aa8114431b90d6c85ec3a87c28b94.png)
一、实验目的本次实验旨在通过实例操作,深入了解线程的概念、创建、同步与通信机制,以及线程在实际编程中的应用。
通过实验,提高对线程的理解和运用能力,为以后开发多线程程序打下坚实基础。
二、实验环境1. 操作系统:Windows 102. 开发工具:Visual Studio 20193. 编程语言:C#三、实验内容1. 线程的基本概念线程是程序执行的最小单位,是操作系统进行资源分配和调度的基本单位。
线程具有以下特点:(1)线程是轻量级的,创建、销毁线程的开销较小。
(2)线程共享进程的资源,如内存、文件等。
(3)线程之间可以并发执行。
2. 线程的创建在C#中,可以使用以下方式创建线程:(1)使用Thread类```csharpThread thread = new Thread(new ThreadStart(MethodName));thread.Start();```(2)使用lambda表达式```csharpThread thread = new Thread(() => MethodName());thread.Start();```(3)使用匿名方法```csharpThread thread = new Thread(delegate () { MethodName(); });thread.Start();```3. 线程的同步线程同步是指多个线程在执行过程中,为了防止资源冲突而采取的协调机制。
C#提供了以下同步机制:(1)互斥锁(Mutex)```csharpMutex mutex = new Mutex();mutex.WaitOne();// 线程同步代码mutex.ReleaseMutex();```(2)信号量(Semaphore)```csharpSemaphore semaphore = new Semaphore(1, 1);semaphore.WaitOne();// 线程同步代码semaphore.Release();```(3)读写锁(ReaderWriterLock)```csharpReaderWriterLock rwlock = new ReaderWriterLock();rwlock.AcquireReaderLock();// 读取操作rwlock.ReleaseReaderLock();```4. 线程的通信线程通信是指线程之间传递消息、共享数据的过程。
操作系统线程同步实验报告
![操作系统线程同步实验报告](https://img.taocdn.com/s3/m/89758808f12d2af90242e697.png)
线程同步实验报告
实验目的:讨论临界区问题及其解决方案。
实验内容:首先创建两个共享数据资源的并发进程,然后分别在没有同步控制机制、采用mutex机制以及使用软件方法(Peterson)的情况下探究并尽量解决所产生的异常情况。
实验结果:(一)结果截图
1、没有同步控制机制
2、使用mutex机制(其中run1、run2是标志进程输出次数)
3、Peterson算法
(二)结果分析
按照输出结果的稳定性来评判一个程序的好坏,那么大体可以总结为:没有使用同步控制机制<mutex机制<软件机制。
mutex机制是实现由一个进程对公共资源进行访问的时候,不允许其它进程对此资源进行访问。
保证了进程之间的互斥性。
软件机制是使用Peterson算法实现进程间的轮流进行以及进程之间的互斥性。
但是实验结果显示每一种方法均存在异常情况,即在一定次数后程序结束。
产生异常的原因大致分为以下几种:1、进程间的相互影响导致在访问同一个共同资源时会出现变量值与理论值产生偏差,使得不满足循环条件;2、针对单处理机的程序在处理多处理机的问题上会出现偏差;3、PC机本身内存可能存在的部分遗留的数据会影响数据的运算。
线程的互斥实验报告总结
![线程的互斥实验报告总结](https://img.taocdn.com/s3/m/cfd5f8dc988fcc22bcd126fff705cc1754275f7c.png)
线程的互斥实验报告总结
本次实验是关于线程互斥的,旨在通过使用互斥锁和信号量等机制,让学生能够更好地理解并掌握线程的互斥操作。
在本次实验中,我们首先学习了互斥锁的概念和使用方法。
互斥
锁是一种最常用的线程同步机制,用来保证多个线程之间的互斥操作。
通过使用互斥锁,我们可以避免两个或多个线程同时访问共享资源而
导致数据异常的问题。
实验中,我们对比了有互斥锁与没有互斥锁对
共享变量的访问结果,明显地看到了在没有互斥锁的情况下,数据会
发生异常。
除了互斥锁,我们还学习了信号量的概念和使用方法。
信号量是
一种用于控制访问共享资源的标志,在多线程程序中广泛应用。
使用
信号量可以保证多个线程间共享资源的安全性,并可以避免资源竞争
和死锁的发生。
在实验中,我们还利用信号量实现了线程的同步和互
斥操作。
通过本次实验,我深感互斥锁和信号量在多线程程序中的重要性。
在多线程编程中,不仅要考虑到线程之间的并发问题,也需要关注到
线程之间的同步和互斥操作。
只有将线程同步和互斥机制运用到多线
程编程中,才能真正保证多线程程序的安全性和正确性。
综上所述,本次实验对于我来说是非常有意义的。
通过学习互斥
锁和信号量等线程同步机制,我对于多线程编程的思想和技术又有了
更深刻的理解和认识。
我相信,在今后的学习和工作中,所学到的知识一定会给我带来更多的帮助和启示。
实验五 多线程程序设计 实验报告
![实验五 多线程程序设计 实验报告](https://img.taocdn.com/s3/m/f6b5b799680203d8ce2f2467.png)
实验五多线程程序设计实验报告一、实验目的1. 熟悉利用Thread 类建立多线程的方法。
2. 熟悉利用Runnable 接口建立多线程的方法。
二、实验原理1. 通过继承Thread 类实现多线程的方法:① 创建一个Thread 类的子类。
② 重写run 方法。
③ 创建这个子类的实例。
④调用子类的start 方法启动线程。
2. 通过Runnable 接口实现多线程的方法:① 创建一个线程类,实现Runnable 接口。
② 实现run 方法。
③ 通过Thread 类中的Thread(Runnable) 构造方法创建一个线程类实例。
④ 调用线程类的start 方法启动线程。
三、实验内容1. 阅读下列程序,分析并上机检验其功能。
class DelayThread extends Thread {private static int count=0;private int no;private int delay;public DelayThread() {count++;no=count;}public void run() {try {for (int i=0;i<10;i++){delay=(int)(Math.random()*5000);sleep(delay);System.out.println(“Thread ”+no+” with a delay ”+delay);} catch(InterruptedException e) { }}}public class MyThread {public static void main(String args[]) {DelayThread thread1 = new DelayThread();DelayThread thread2 = new DelayThread();thread1.start();thread2.start();try {Thread.sleep(1000);} catch (InterruptedException e) {System.out.println(“Thread wrong”);}}}2. 利用Runnable 接口修改上面的程序,使之完成同样的功能。
创建线程的实验报告
![创建线程的实验报告](https://img.taocdn.com/s3/m/9316e24ca31614791711cc7931b765ce05087ad6.png)
一、实验目的1. 理解线程的概念和作用。
2. 掌握在Java中创建线程的方法。
3. 学习线程的生命周期和线程同步。
4. 熟悉线程的调度和同步机制。
二、实验环境1. 操作系统:Windows 102. 开发工具:IntelliJ IDEA3. 编程语言:Java三、实验内容1. 创建线程2. 线程生命周期3. 线程同步4. 线程调度四、实验步骤1. 创建线程(1)继承Thread类创建线程```javapublic class MyThread extends Thread { @Overridepublic void run() {// 线程要执行的任务System.out.println("子线程:" + Thread.currentThread().getName());}}```(2)实现Runnable接口创建线程```javapublic class MyRunnable implements Runnable {@Overridepublic void run() {// 线程要执行的任务System.out.println("子线程:" +Thread.currentThread().getName());}}```2. 线程生命周期线程生命周期包括以下五个状态:(1)新建(New):线程对象被创建后,处于此状态。
(2)就绪(Runnable):线程对象被创建后,调用start()方法,线程进入就绪状态。
(3)运行(Running):线程被调度到CPU上执行,处于运行状态。
(4)阻塞(Blocked):线程因为某些原因无法执行,进入阻塞状态。
(5)终止(Terminated):线程执行完毕或被强制终止,处于终止状态。
以下代码演示了线程的生命周期:```javapublic class LifeCycleDemo {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable());System.out.println("线程状态:" + thread.getState());thread.start();System.out.println("线程状态:" + thread.getState());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程状态:" + thread.getState());}}```3. 线程同步线程同步是为了避免多个线程同时访问共享资源时出现冲突。
建立线程的实验报告(3篇)
![建立线程的实验报告(3篇)](https://img.taocdn.com/s3/m/b1deeb505b8102d276a20029bd64783e08127d4a.png)
第1篇一、实验目的1. 理解线程的概念和作用;2. 掌握在C++中创建和使用线程的方法;3. 了解线程同步机制,如互斥锁、条件变量等;4. 分析线程间的通信和协作。
二、实验环境1. 操作系统:Windows 102. 编译器:Visual Studio 20193. 编程语言:C++三、实验内容本次实验主要分为以下几个部分:1. 线程的基本概念和作用;2. 创建和使用线程;3. 线程同步机制;4. 线程间的通信和协作。
四、实验步骤1. 线程的基本概念和作用线程是程序执行过程中的一个独立单位,它包含程序执行所需的基本信息,如程序计数器、寄存器等。
线程的主要作用是提高程序的执行效率,实现并发执行。
2. 创建和使用线程在C++中,可以使用`std::thread`类来创建线程。
以下是一个简单的例子:```cppinclude <iostream>void printNumber(int n) {for (int i = 0; i < n; ++i) {std::cout << i << std::endl;}}int main() {std::thread t1(printNumber, 10); // 创建线程,传入函数和参数std::thread t2(printNumber, 20);t1.join(); // 等待线程t1执行完毕t2.join(); // 等待线程t2执行完毕return 0;}```在上面的代码中,我们创建了两个线程`t1`和`t2`,分别执行`printNumber`函数。
使用`join`函数可以等待线程执行完毕。
3. 线程同步机制线程同步机制用于解决多线程在执行过程中可能出现的数据竞争、死锁等问题。
以下是一些常用的线程同步机制:(1)互斥锁(Mutex)互斥锁用于保护共享资源,确保同一时刻只有一个线程可以访问该资源。
以下是一个使用互斥锁的例子:```cppinclude <iostream>include <mutex>std::mutex mtx;void printNumber(int n) {mtx.lock(); // 获取互斥锁for (int i = 0; i < n; ++i) {std::cout << i << std::endl;}mtx.unlock(); // 释放互斥锁}int main() {std::thread t1(printNumber, 10);std::thread t2(printNumber, 20);t1.join();t2.join();return 0;}```(2)条件变量(Condition Variable)条件变量用于在线程间实现等待和通知机制。
线程互斥的实验报告
![线程互斥的实验报告](https://img.taocdn.com/s3/m/1fb00a60a4e9856a561252d380eb6294dd882287.png)
线程互斥的实验报告线程互斥是操作系统中重要的概念之一。
在线程并发执行的情况下,多个线程可能会同时访问共享资源,如果没有互斥机制进行控制,就会出现数据竞争和不确定性的情况。
为了避免这种情况的发生,需要通过互斥机制对多个线程的并发访问进行合理控制。
二、实验目的本实验旨在通过编写程序,实现线程互斥的功能,进一步理解和掌握线程互斥的概念和原理,并验证互斥机制的有效性。
三、实验过程1. 创建共享资源:首先,我们创建一个共享资源,例如全局变量x。
2. 创建多个线程并发执行:通过创建多个线程来模拟多个并发执行的场景,每个线程都有访问共享资源的需求。
3. 创建互斥锁:使用操作系统提供的互斥锁实现机制来实现线程互斥,确保同时只有一个线程可以访问共享资源。
4. 设置互斥锁的加锁和解锁:在线程访问共享资源之前使用互斥锁进行加锁,在访问完共享资源之后进行解锁,以确保资源的正确性和完整性。
5. 运行程序并观察结果:运行多个线程并发执行的程序,通过打印输出等方式观察线程的执行情况,确保互斥机制的有效性。
四、实验结果与分析在实验过程中,我们创建了一个全局变量x作为共享资源,并创建了两个线程t1和t2来同时访问该变量。
通过使用互斥锁的机制,我们保证了同时只有一个线程可以访问变量x。
在线程t1对变量x进行操作之前,需要先获得互斥锁的加锁,操作完成后再进行解锁。
同样地,线程t2在操作变量x之前也需要获得互斥锁的加锁,操作完成后再进行解锁。
经过多次运行实验,观察到线程t1和t2的执行顺序是随机的,有时t1先执行,有时t2先执行。
这是因为线程的调度和执行是由操作系统决定的,而与我们代码编写的顺序无关。
但无论线程t1和t2的执行顺序如何,由于我们使用了互斥锁的机制,保证了对变量x的访问是互斥的,即同时只能有一个线程在操作变量x。
这也是我们对互斥机制的期望结果。
五、实验总结通过本实验,我们深入理解了线程互斥的概念和原理,并成功实现了线程互斥的功能。
多线程并发实验报告
![多线程并发实验报告](https://img.taocdn.com/s3/m/af9b28a5760bf78a6529647d27284b73f342364c.png)
一、实验目的1. 理解多线程并发编程的基本概念和原理;2. 掌握Java多线程编程的基本方法和技巧;3. 学习线程同步机制,解决线程安全问题;4. 熟悉线程调度策略,提高程序性能。
二、实验环境1. 操作系统:Windows 102. 开发工具:IntelliJ IDEA3. JDK版本:1.8三、实验内容1. 线程创建与启动2. 线程同步与互斥3. 线程通信与协作4. 线程池与线程调度5. 线程局部变量与共享变量四、实验步骤及结果分析1. 线程创建与启动实验步骤:(1)创建一个继承自Thread类的子类;(2)重写run()方法,定义线程的执行逻辑;(3)创建Thread对象,并调用start()方法启动线程。
实验结果:成功创建并启动两个线程,分别执行各自的run()方法。
2. 线程同步与互斥实验步骤:(1)创建一个共享资源;(2)使用synchronized关键字声明同步方法或同步代码块;(3)在同步方法或同步代码块中访问共享资源。
实验结果:线程在访问共享资源时,能够保证互斥,防止数据不一致。
3. 线程通信与协作实验步骤:(1)使用wait()和notify()方法实现线程间的通信;(2)创建共享对象,作为线程间通信的媒介;(3)在等待线程中调用wait()方法,在通知线程中调用notify()方法。
实验结果:线程能够通过wait()和notify()方法实现通信与协作,完成特定任务。
4. 线程池与线程调度实验步骤:(1)使用Executors工厂方法创建线程池;(2)提交任务到线程池;(3)关闭线程池。
实验结果:线程池能够有效地管理线程,提高程序性能。
5. 线程局部变量与共享变量实验步骤:(1)创建线程局部变量;(2)创建共享变量;(3)在各个线程中访问和修改线程局部变量与共享变量。
实验结果:线程局部变量在各个线程中独立存在,不会相互干扰;共享变量在各个线程中共享,需要使用同步机制保证数据一致性。
多进线程实验报告
![多进线程实验报告](https://img.taocdn.com/s3/m/bc730157773231126edb6f1aff00bed5b8f3734d.png)
一、实验目的1. 理解多线程的概念及其在程序设计中的应用。
2. 掌握Java语言中多线程的创建、同步、通信等基本技术。
3. 熟悉线程池的使用,提高程序执行效率。
4. 分析多线程程序中的线程安全问题,并采取相应的措施解决。
二、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:Eclipse IDE4. 硬件环境:Intel Core i5处理器,4GB内存三、实验内容1. 创建多线程程序,实现两个线程同时执行。
2. 实现线程同步,防止数据竞态。
3. 使用线程池提高程序执行效率。
4. 分析多线程程序中的线程安全问题,并提出解决方案。
四、实验步骤1. 创建多线程程序在Java中,可以使用Thread类或Runnable接口创建线程。
以下是一个使用Runnable接口创建多线程的示例代码:```javapublic class MyThread implements Runnable {public void run() {System.out.println("线程 " + Thread.currentThread().getName() + " 正在执行");}}public class Main {public static void main(String[] args) {MyThread myThread1 = new MyThread();MyThread myThread2 = new MyThread();Thread thread1 = new Thread(myThread1);Thread thread2 = new Thread(myThread2);thread1.start();thread2.start();}}```2. 实现线程同步在多线程程序中,当多个线程访问共享资源时,可能会出现数据竞态问题。
多线程编程实验报告
![多线程编程实验报告](https://img.taocdn.com/s3/m/a816fe2c03768e9951e79b89680203d8ce2f6a2b.png)
一、实验目的1. 理解多线程编程的基本概念和原理。
2. 掌握多线程的创建、同步、通信和调度等关键技术。
3. 通过实验加深对多线程编程的理解,提高编程能力。
二、实验环境硬件:PC机软件:VMware虚拟机、Linux系统、C/C++编译器三、实验内容1. 多线程创建与运行2. 线程同步与互斥3. 线程通信与协作4. 线程调度与优先级5. 生产者-消费者问题四、实验步骤1. 多线程创建与运行(1)创建线程:使用pthread_create函数创建线程,指定线程的入口函数、参数、线程属性等。
(2)线程运行:编写线程入口函数,实现线程需要执行的任务。
(3)线程结束:在线程入口函数中执行任务后,使用pthread_exit函数结束线程。
2. 线程同步与互斥(1)互斥锁:使用pthread_mutex_lock和pthread_mutex_unlock函数实现互斥锁,保证同一时刻只有一个线程访问共享资源。
(2)条件变量:使用pthread_cond_wait和pthread_cond_signal函数实现条件变量,实现线程间的同步与协作。
(3)读写锁:使用pthread_rwlock_rdlock和pthread_rwlock_wrlock函数实现读写锁,允许多个线程同时读取共享资源,但只有一个线程可以写入。
3. 线程通信与协作(1)线程间通信:使用pthread_cond_signal、pthread_cond_broadcast、pthread_barrier_wait等函数实现线程间的通信。
(2)线程协作:使用pthread_barrier_init、pthread_barrier_wait函数实现线程间的协作,确保所有线程到达某个点后再继续执行。
4. 线程调度与优先级(1)线程调度:了解操作系统的线程调度算法,如时间片轮转、优先级调度等。
(2)线程优先级:使用pthread_setschedparam函数设置线程的调度策略和优先级。
线程通讯实验报告
![线程通讯实验报告](https://img.taocdn.com/s3/m/5ec4b186ac51f01dc281e53a580216fc710a5350.png)
一、实验目的1. 理解线程通讯的基本概念和机制。
2. 掌握常用的线程通讯方法,如管道、信号量、消息队列等。
3. 通过实验,加深对线程同步和互斥的理解。
4. 提高编程能力,掌握多线程编程技术。
二、实验环境1. 操作系统:Linux2. 编程语言:C/C++3. 开发环境:GCC编译器三、实验内容本次实验主要涉及以下内容:1. 管道(Pipe)通讯2. 命名管道(Named Pipe)通讯3. 信号量(Semaphore)通讯4. 消息队列(Message Queue)通讯5. 共享内存(Shared Memory)通讯6. 套接字(Socket)通讯四、实验步骤及结果分析1. 管道(Pipe)通讯实验步骤:- 创建两个进程,父进程和子进程。
- 父进程向管道写入数据。
- 子进程从管道读取数据。
实验结果:- 父进程成功向管道写入数据。
- 子进程成功从管道读取数据。
结论:管道是一种半双工的通信方式,适用于具有亲缘关系的进程间的通信。
2. 命名管道(Named Pipe)通讯实验步骤:- 创建两个无亲缘关系的进程,进程A和进程B。
- 进程A向命名管道写入数据。
- 进程B从命名管道读取数据。
实验结果:- 进程A成功向命名管道写入数据。
- 进程B成功从命名管道读取数据。
结论:命名管道是一种半双工的通信方式,适用于无亲缘关系的进程间的通信。
3. 信号量(Semaphore)通讯实验步骤:- 创建两个线程,线程A和线程B。
- 线程A和线程B使用信号量实现同步。
实验结果:- 线程A和线程B成功实现同步。
结论:信号量是一种常用的线程同步机制,可以防止多个线程同时访问共享资源。
4. 消息队列(Message Queue)通讯实验步骤:- 创建两个线程,线程A和线程B。
- 线程A向消息队列发送消息。
- 线程B从消息队列接收消息。
实验结果:- 线程A成功向消息队列发送消息。
- 线程B成功从消息队列接收消息。
结论:消息队列是一种高效的线程间通信方式,可以克服信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
多线程求和实验报告
![多线程求和实验报告](https://img.taocdn.com/s3/m/e8e450d550e79b89680203d8ce2f0066f533648e.png)
多线程求和实验报告引言在计算机科学领域,多线程技术被广泛应用于提高程序性能和利用多核处理器的潜力。
本实验旨在通过使用多线程技术来实现一个求和程序,以探索多线程在计算密集型任务中的优势。
实验步骤1. 设计线程数量:根据计算机的硬件配置和任务要求,选择合适数量的线程。
在我们的实验中,我们根据计算机CPU核心数选择了4个线程。
2. 创建线程:使用适当的编程语言(在本实验中我们选择了Python),创建所需数量的线程。
3. 划分任务:将要执行的任务划分为多个子任务,每个线程负责执行其中的一部分。
在本实验中,我们要计算的是1到1000000之间的所有整数的总和,我们将其划分为4个子任务,分别由4个线程执行。
4. 并行计算:启动线程并执行各自的子任务。
每个线程计算部分总和后,将结果返回给主线程。
5. 汇总结果:主线程将所有接收到的结果汇总,得到最终的总和。
6. 输出结果:将最终的总和输出到控制台或文件中。
实验结果我们将实验程序运行了多次,并记录了不同线程数量下的运行时间,以比较不同线程数量对程序性能的影响。
下表为每种线程数量下的运行时间(单位:毫秒):线程数量运行时间1 8432 5414 4038 556从上表中我们可以观察到以下现象:- 随着线程数量的增加,运行时间先减少后增加。
这是因为当线程数量小于或等于CPU核心数量时,多线程能够充分利用多核处理器的并行计算能力,从而加快运行速度;当线程数量大于CPU核心数量时,线程切换的开销会降低性能,导致运行时间增加。
- 线程数量为4时,表现出最佳的性能。
这是因为我们的计算机拥有4个CPU 核心,因此4个线程可以充分利用这些核心,达到最佳的性能。
结论本实验通过多线程技术实现了一个求和程序,并通过实验结果验证了多线程在计算密集型任务中的优势。
通过合理划分任务和选择适当的线程数量,我们能够充分利用多核处理器的并行计算能力,从而加快程序的运行速度。
然而,当线程数量大于CPU核心数量时,线程切换的开销会降低性能,因此在选择线程数量时需要考虑硬件配置和任务的特点。
java多线程实验报告
![java多线程实验报告](https://img.taocdn.com/s3/m/67c771b37d1cfad6195f312b3169a4517723e524.png)
java多线程实验报告Java多线程实验报告。
一、实验目的。
本实验旨在通过编写Java程序,实现多线程的基本操作,包括线程的创建、启动、暂停、恢复和终止,以及线程间的通信和同步,从而加深对Java多线程编程的理解和掌握。
二、实验内容。
1. 线程的创建和启动。
在Java中,可以通过继承Thread类或实现Runnable接口来创建线程。
在本次实验中,我们将通过这两种方式来创建线程,并分别启动它们,观察线程的执行情况。
2. 线程的暂停和恢复。
线程的暂停和恢复可以通过调用Thread类的suspend()和resume()方法来实现。
我们将在实验中使用这两个方法来暂停和恢复线程的执行,以及分析其可能存在的问题和风险。
3. 线程的终止。
线程的终止可以通过调用Thread类的stop()方法来实现。
然而,stop()方法已经被废弃,因为它可能导致线程的不安全状态。
在本次实验中,我们将探讨更安全的线程终止方式,并进行实际操作。
4. 线程间的通信和同步。
在多线程编程中,线程间的通信和同步是非常重要的。
我们将通过使用wait()、notify()和notifyAll()方法,以及synchronized关键字,来实现线程间的通信和同步,从而避免出现竞态条件和死锁等问题。
三、实验过程。
1. 创建并启动线程。
首先,我们创建一个继承自Thread类的子类,并重写其run()方法,在run()方法中编写线程的执行逻辑。
然后,我们创建一个实现了Runnable接口的类,并实现其run()方法。
最后,我们分别创建这两种线程,并启动它们,观察它们的执行情况。
2. 暂停和恢复线程。
在线程执行过程中,我们调用suspend()方法来暂停线程的执行,然后调用resume()方法来恢复线程的执行。
在实验中,我们将分析这种暂停和恢复方式可能存在的问题,并寻找更安全的替代方案。
3. 终止线程。
我们将探讨如何安全地终止线程的执行,避免使用stop()方法可能导致的线程不安全问题。
线程控制实验报告(3篇)
![线程控制实验报告(3篇)](https://img.taocdn.com/s3/m/3be92a2d777f5acfa1c7aa00b52acfc788eb9f33.png)
第1篇一、实验背景线程是操作系统中实现并发执行的基本单位,它允许程序在同一时间内执行多个任务。
线程控制实验旨在通过实际操作,加深对线程概念、线程同步与互斥机制的理解,并掌握线程的创建、同步与互斥方法。
二、实验目的1. 理解线程的概念及其在操作系统中的作用。
2. 掌握线程的创建、同步与互斥方法。
3. 熟悉线程调度与同步在实际编程中的应用。
4. 通过实验,提高对多线程编程的理解和实际操作能力。
三、实验环境操作系统:Windows 10编程语言:Java开发工具:Eclipse四、实验内容1. 线程的创建与启动实验步骤:(1)创建一个名为ThreadDemo的Java类,继承自Thread类。
(2)在ThreadDemo类中重写run()方法,实现线程要执行的任务。
(3)在main方法中创建ThreadDemo类的实例,并调用start()方法启动线程。
实验代码:```javapublic class ThreadDemo extends Thread {@Overridepublic void run() {// 线程要执行的任务System.out.println("线程运行:" +Thread.currentThread().getName());}public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();threadDemo.start(); // 启动线程}}```2. 线程同步与互斥实验步骤:(1)创建一个名为SyncDemo的Java类,包含一个共享资源和一个同步方法。
(2)在SyncDemo类中,使用synchronized关键字声明同步方法,实现线程间的同步。
(3)在main方法中创建多个ThreadDemo类的实例,并启动线程,观察线程同步与互斥的效果。
实验代码:```javapublic class SyncDemo {private int count = 0;public synchronized void increment() {count++;System.out.println(Thread.currentThread().getName() + ":count=" + count);}public static void main(String[] args) {SyncDemo syncDemo = new SyncDemo();Thread thread1 = new Thread(() -> {for (int i = 0; i < 5; i++) {syncDemo.increment();}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 5; i++) {syncDemo.increment();}});thread1.start();thread2.start();}}```3. 线程通信实验步骤:(1)创建一个名为ThreadCommunication的Java类,包含一个共享资源和一个同步方法。
多线程基础实验报告
![多线程基础实验报告](https://img.taocdn.com/s3/m/f8fb238c250c844769eae009581b6bd97f19bcac.png)
一、实验目的1. 理解多线程的概念及其在程序设计中的应用。
2. 掌握在Java中创建和使用线程的基本方法。
3. 学习线程的同步和互斥机制,理解死锁、线程安全等概念。
4. 了解线程的生命周期及其状态转换。
二、实验环境- 操作系统:Windows 10- 开发工具:Eclipse IDE- 编程语言:Java三、实验内容本次实验主要围绕以下内容展开:1. 线程的基本操作:创建线程、启动线程、线程的执行、线程的终止。
2. 线程的同步与互斥:使用synchronized关键字实现线程同步,防止数据竞态。
3. 线程的通信:使用wait()、notify()、notifyAll()方法实现线程间的通信。
4. 线程池:使用ExecutorService创建线程池,提高线程复用率。
5. 线程的生命周期:观察线程的状态转换,理解线程的创建、运行、阻塞、终止等过程。
四、实验步骤1. 创建线程:- 通过继承Thread类创建线程,并重写run()方法。
- 通过实现Runnable接口创建线程,将任务封装在Runnable对象中。
- 使用匿名内部类创建线程。
2. 线程的同步与互斥:- 使用synchronized关键字对共享资源进行加锁,保证同一时间只有一个线程可以访问。
- 使用ReentrantLock类实现线程同步,提供更丰富的锁操作。
3. 线程的通信:- 使用wait()、notify()、notifyAll()方法实现线程间的通信,解决生产者-消费者问题。
4. 线程池:- 使用ExecutorService创建线程池,提高线程复用率。
- 使用Future接口获取线程执行结果。
5. 线程的生命周期:- 使用Thread类的方法观察线程的状态,如isAlive()、getState()等。
五、实验结果与分析1. 创建线程:- 通过继承Thread类、实现Runnable接口和匿名内部类成功创建了线程,并观察到线程的执行。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
线程实验报告黄澄宇3200709112411.分析(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.javaimport .*;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){System.out.println("Waiting for Connection..."); transferfile t=new transferfile(soc.accept());}}}class transferfile extends Thread{Socket ClientSoc;DataInputStream din;DataOutputStream dout;transferfile(Socket soc){try{ClientSoc=soc;din=new DataInputStream(ClientSoc.getInputStream()); dout=new DataOutputStream(ClientSoc.getOutputStream()); System.out.println("FTP Client Connected...");start();}catch(Exception ex){}}void SendFile() throws Exception{String filename=din.readUTF();File f=new File(filename);if(!f.exists()){dout.writeUTF("File Not Found"); return;}else{dout.writeUTF("READY"); FileInputStream fin=new FileInputStream(f); int ch;do{ch=fin.read();dout.writeUTF(String.valueOf(ch));}while(ch!=-1);fin.close();dout.writeUTF("File Receive Successfully"); }}void ReceiveFile() throws Exception{String filename=din.readUTF();if(pareTo("File not found")==0) {return;}File f=new File(filename);String option;if(f.exists()){dout.writeUTF("File Already Exists"); option=din.readUTF();}else{dout.writeUTF("SendFile");option="Y";if(pareTo("Y")==0){FileOutputStream fout=new FileOutputStream(f); int ch;String temp;do{temp=din.readUTF();ch=Integer.parseInt(temp);if(ch!=-1){fout.write(ch);}}while(ch!=-1);fout.close();dout.writeUTF("File Send Successfully");}else{return;}public void run(){while(true){try{System.out.println("Waiting for Command..."); String Command=din.readUTF();if(pareTo("GET")==0){System.out.println("\tGET Command Received..."); SendFile();continue;}else if(pareTo("SEND")==0){System.out.println("\tSEND Command Receiced "); ReceiveFile();continue;}else if(pareTo("DISCONNECT")==0)System.out.println("\tDisconnect Command Received "); System.exit(1);}}catch(Exception ex){}}}}/FTPClient.javaimport .*;import java.io.*;import java.util.*;class FTPClient{public static void main(String args[]) throws Exception {Socket soc=new Socket("127.0.0.1",5127); transferfileClient t=new transferfileClient(soc);t.displayMenu();}class transferfileClient{Socket ClientSoc;DataInputStream din;DataOutputStream dout;BufferedReader br;transferfileClient(Socket soc){try{ClientSoc=soc;din=new DataInputStream(ClientSoc.getInputStream()); dout=new DataOutputStream(ClientSoc.getOutputStream()); br=new BufferedReader(new InputStreamReader(System.in)); }catch(Exception ex){}}void SendFile() throws ExceptionString filename;System.out.print("Enter File Name :");filename=br.readLine();File f=new File(filename);if(!f.exists()){System.out.println("File not Exists");dout.writeUTF("File not found");return;}dout.writeUTF(filename);String msgFromServer=din.readUTF();if(pareTo("File Already Exists")==0){String Option;System.out.println("File Already Exists Want to OverWrite (Y/N) ?"); Option=br.readLine();if(Option=="Y"){dout.writeUTF("Y");}else{dout.writeUTF("N");return;}}System.out.println("Sending File..."); FileInputStream fin=new FileInputStream(f); int ch;do{ch=fin.read();dout.writeUTF(String.valueOf(ch));}while(ch!=-1);fin.close();System.out.println(din.readUTF());}void ReceiveFile() throws Exception{String fileName;System.out.print("Enter File Name :"); fileName=br.readLine();dout.writeUTF(fileName);String msgFromServer=din.readUTF();if(pareTo("File Not Found")==0){System.out.println("File not found on Server...");return;}else if(pareTo("READY")==0){System.out.println("Receiving File... ");File f=new File(fileName);if(f.exists()){String Option;System.out.println("File Already Exists. Want to OverWrite (Y/N) ?"); Option=br.readLine();if(Option=="N"){dout.flush();return;}}FileOutputStream fout=new FileOutputStream(f); int ch;String temp;do{temp=din.readUTF();ch=Integer.parseInt(temp);if(ch!=-1){fout.write(ch);}}while(ch!=-1);fout.close();System.out.println(din.readUTF());}}public void displayMenu() throws Exception {while(true){System.out.println("[ MENU ]");System.out.println("1.Send File");System.out.println("2.Receive File"); System.out.println("3.Exit"); System.out.print("\nEnter Choice :"); int choice;choice=Integer.parseInt(br.readLine()); if(choice==1){dout.writeUTF("SEND");SendFile();}else if(choice==2){dout.writeUTF("GET"); ReceiveFile();}else{dout.writeUTF("DISCONNECT"); System.exit(1);}}}}。