系统io

本学期的计算机系统课接近尾声,这是我要写的最后一篇博客,大概也是我最想要写的一篇,结合备考软考和计算机系统课上老师讲的一些知识谈一谈关于系统io,并且结合我在项目中的实践谈一谈学习了计算机系统对我的帮助。
io操作的几种方式
1.直接程序控制
直接程序控制是指外设数据的输入输出过程是在CPU执行程序的控制下完成的。这种方式分为无条件传送和程序查询方式两种情况。
分为无条件传送和程序查询方式。
(1)无条件传送:
在此情况下。外设总是准备好的,他可以无条件的随时接收CPU发来的输出数据,也能够无条件地随时向cpu提供需要输入的数据。
(2)程序查询方式
在这种方式下,利用查询方式进行输入输出,就是通过cpu执行程序来查询外设状态,判断外设是否准备好接受数据或接收好了向cpu输入的数据。根据这种状态,cpu有针对性的为外设的输入输出服务。
2.中断方式
利用中断的方式完成数据的输入输出过程为:当I/O系统与外设交换数据时,CPU无需等待也不必去查询I/O的状态,而可以抽身来处理其他的任务。当系统I/O准备好以后,则发出中断请求信号通知CPU,CPU接到中断请求信号后,保存正在执行的程序现场,转入I/O中断服务程序的执行,完成与I/O系统的交换数据,然后再返回被打断的程序继续执行。与程序控制方式相比,中断方式因为CPU无需等待而提高了效率。
3.DMA方式
DMA方式是指数据在内存与I/O设备间的直接成块传送,即在内存与I/O设备间传送一个数据块的过程中,不需要CPU的任何干涉,只需要CPU在过程开始启动与过程结束时的处理,实际操作由DMA硬件直接执行完成,CPU在此传送过程中可做别的事情。
我遇到的关于I/O的问题
这学期,在做项目时,我深刻的了解到了理解计算机系统的重要性。在做一个关于人工智能的项目时,我需要从一个视频中一帧一帧的读取图片,然后将图片显示在Frame界面上,(这中间会用级联分类器做一些检测的工作)当时错误的代码大概是下面这个样子(记得不是很清楚了),也就是说因为opencv在视频中读取的图片是Mat类型的而在Frame上不能直接显示这种类型的图片,因此我当时的想法就是直接把这个图片存储在磁盘上,然后直接把路径传给UserInter,UserInter在磁盘上去读这张图然后显示出来,也就是因为这个想法,我在这个部分卡了一个上午,程序没有按照我的想法进行输出,UserInter上一帧的图片也没有显示,这还不是最崩溃的,最崩溃的是居然一条的报错信息也没有,没有报错信息的错误是最令人难以修改的,我大胆的猜测这个问题出在哪里,机缘巧合之下我设置了一个变量,利用这个变量,我让读取视频帧图片与UserInter显示图片之间存在了一个时间差,没想到图片居然显示出来了,我又仔细思索,想到了计算机系统课上的DMA的I/O方式,终于想出了问题的所在,程序执行的速度很快,在磁盘上存数据又很慢,在DMA方式下CPU不会等待磁盘存储图片操作的完成就会去执行接下来的语句,这样,当程序去显示某一帧的图片时,实际上磁盘中还没有存上这一张图片,UserInter当然也就无法显示了。之后我换了另一种方法,直接把Mat类型的图片转化为了BufferedImage,在内存中进程图片的传输,问题解决了,功能也实现了,至此一个上午过去了,这个问题也终于解决了。经过这件事,我深深地感受到了了解计算机系统的重要性,谁知道以后还会遇到什么千奇百怪难以解决的问题,了解计算机的底层才能应对一切。
出错的代码

	public void run() {
		if(!video.isOpened()) {				
			System.out.println("Open File Error");//无法打开文件异常事件处理
		}else {
			Mat videoFrame=new Mat();
			Mat result=new Mat();
			while(true){
				if(userInter.videoPlay) {
						video.read(videoFrame);
				}
				for(int k=0;k<detections.size();k++) {
					videoFrame=detections.get(k).ObjectDetection(videoFrame);
				}
				for(int i=0;i<detections.size();i++) {
					userInter.setText("场景中有"+detections.get(i).objectNumber+"个"+detections.get(i).name+"\n");
//					System.out.println("场景中有"+detections.get(i).objectNumber+"个"+detections.get(i).name+"\n");
					for(int j=0;j<detections.get(i).objectNumber;j++) {
						userInter.setText("第"+(j+1)+"个"+"的坐标为("+detections.get(i).x[j]+","+detections.get(i).y[j]+")\n");
					}
					detections.get(i).objectNumber=0;
				}
				Imgcodecs.imwrite(imagePath);
				userInter.setVideoImage(imagePath);//设置用户界面显示的图片
				userInter.repaint();
//				try{
//					Thread.sleep(10);
//				}catch(InterruptedException  e) {
//					e.printStackTrace();
//				}
			}
		}
    }

改正后的代码

	public void run() {
		if(!video.isOpened()) {				
			System.out.println("Open File Error");//无法打开文件异常事件处理
		}else {
			Mat videoFrame=new Mat();
			Mat result=new Mat();
			while(true){
				if(userInter.videoPlay) {
						video.read(videoFrame);
				}
				for(int k=0;k<detections.size();k++) {
					videoFrame=detections.get(k).ObjectDetection(videoFrame);
				}
				for(int i=0;i<detections.size();i++) {
					userInter.setText("场景中有"+detections.get(i).objectNumber+"个"+detections.get(i).name+"\n");
//					System.out.println("场景中有"+detections.get(i).objectNumber+"个"+detections.get(i).name+"\n");
					for(int j=0;j<detections.get(i).objectNumber;j++) {
						userInter.setText("第"+(j+1)+"个"+"的坐标为("+detections.get(i).x[j]+","+detections.get(i).y[j]+")\n");
					}
					detections.get(i).objectNumber=0;
				}
				Image image=matToBufferedImage(videoFrame);
				userInter.setVideoImage(image);//设置用户界面显示的图片
				userInter.repaint();
//				try{
//					Thread.sleep(10);
//				}catch(InterruptedException  e) {
//					e.printStackTrace();
//				}
			}
		}
    }

事实上我在使用java代码调用python代码是也遇到了一个让我记忆深刻的错误,python子进程的阻塞导致父进程也无法正常进行,最后也是依靠计算机系统的知识解决的,虽然这学期的计算机系统课已经结束了,但是我想我对计算机系统的学习才刚刚开始。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值