操作系统实验:线程的创建与撤销_线程的创建与撤销实验报告-程序员宅基地

技术标签: 操作系统  多线程  多进程  

一、实验目的

(1)熟悉windows系统提供的线程创建与撤销系统调用。
(2)掌握windows系统环境下线程的创建与撤销方法。
(3)掌握CreateThread()函数和ExitThread()函数。 

二、实验准备

(1).实验在windows XP,VC++6.0环境下进行。在这一步,安装了Windows XP虚拟机,学会了创建一个控制台工程文件。

(2).百度句柄的含义:句柄(handle),有多种意义,第一种解释:句柄是一种特殊的智能指针 。当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。句柄是Windows用来标志应用程序中建立的或是适用的对象的唯一整数,Windows大量使用了句柄来标识对象。

(3).参照实验指导学习函数原型--CreateThread()函数:--线程创建
	HANDLE CreateThread(
  		LPSECURITY_ATTRIBUTES   IpThreadAttributes,
  		DWORD                   dwStackSize,
  		LPTHREAD_START_ROUTINE  IpStartAddress,
  		LPVOID 					IpParameter,
  		DWORD                   dwCreationFlags,
  		LPDWORD                 IpThreadId
  	);
	!!!实例化:HANDLE h1 = CreateThread( NULL, 0, Fun1, NULL, 0, NULL );
	<1>.参数IpThreadAttributes指定线程安全属性,当其为NULL时,则线程获取默认安全描述符。
	<2>.参数dwStackSize指定线程堆栈的初始大小,以字节为单位。如果此参数为0,则新线程使用可执行文件的默认大小。
	<3>.参数IpStartAddress指定由线程执行的自定义函数的指针。
	<4>.参数IpParameter指定自定义函数的参数。
	<5>.参数dwCreationFlags指定线程创建后所处的状态。该值为0,表示线程创建后立即执行。
	<6>.参数IpThreadId指定接收线程标识符的变量的指针。该参数为 NULL,则不返回线程标识符。
	---如果函数成功,则返回值是新线程的句柄。如果函数失败,则返回值为NULL。
	
(4).参照实验指导学习函数原型--ExitThread()函数:--撤销进程
	<1>.ExitThread()用于撤销当前进程。
	<2>.该函数没有返回值。
	<3>.用法举例:ExitThread(0);//参数0表示要撤销进程中的所有线程
	
(5).参照实验指导学习函数原型--TerminateThread()函数:--终止线程
	TerminateThread()用于终止当前线程。该函数与ExitThread()的区别在于,ExitThread()在撤销线程时将该线程所拥有的资源全部归还给系统,而TerminateThread()不归还资源。在实验中用ExitThread()函数居多。
	
(6).参照实验指导学习函数原型--Sleep()函数:--挂起线程
	该函数没有返回值。
	
(7).参照实验指导学习函数原型--CloseHandle()函数:--关闭句柄
	返回值:如果函数调用成功,则返回值为非0值;如果函数调用失败,则返回值为0.若要得到更多的错误信息,调用函数GetLastError()查询。

三、实验内容

(一)实验内容
实验1.使用系统调用CreatThread()创建一个子线程,并在子线程中显示;Thread is Running!.为了能让用户清楚地看到线程的运行情况,使用Sleep()使线程挂起5s,之后使用ExitThread(0)撤销进程.

实验2.模仿教学视频中的程序,改写一个吃苹果进程,采用多线程‘吃苹果’与单一线程‘吃苹果’做对比。了解多线程的运行原理。
(二)主要代码:

实验一:

#include "stdafx.h"
#include "01.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

void ThreadName1();
static HANDLE hHandle1=NULL;
DWORD dwThreadID1;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	hHandle1 = CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
		0,
		(LPTHREAD_START_ROUTINE) ThreadName1,
		(LPVOID) NULL,
		0, &dwThreadID1 );
	Sleep(5000);
	CloseHandle(hHandle1);
	ExitThread(0);

	return nRetCode;
}

void ThreadName1()
{
	printf("Thread is running!");
}

实验二:

#include "stdafx.h"
#include "011.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CWinApp theApp;

using namespace std;

void eatApple(int number){
	Sleep((3 - number)*1000);
	printf("I'm eatting #%d apples.\n",number);
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	HANDLE h1 = NULL;
	HANDLE h2 = NULL;
	HANDLE h3 = NULL;
	DWORD Th1 = NULL;
	DWORD Th2 = NULL;
	DWORD Th3 = NULL;

	int a=0;
	int b=1;
	int c=2;
	h1 = CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
		0,
		(LPTHREAD_START_ROUTINE) eatApple,
		(LPVOID) a,
		0, &Th1 );
	h2 = CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
		0,
		(LPTHREAD_START_ROUTINE) eatApple,
		(LPVOID) b,
		0, &Th2 );
	h3 = CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
		0,
		(LPTHREAD_START_ROUTINE) eatApple,
		(LPVOID) c,
		0, &Th3 );

	eatApple(a);
	eatApple(b);
	eatApple(c);
	
	ExitThread(0);
	return nRetCode;
}

四、实验结果与总结

实验一总结:
   在Windows系统中进程是资源的拥有者,线程是系统调用的基本单位。  
   进程创建后,其主线程也随即被创建。在该实验中,有创建了一个名为  
   ThreadName1的子线程,该子线程与主线程并并发的被系统调度。  
   为了能让用户清楚地看到线程的运行情况,在主线程创建了子线程之后,  
   将主线程挂起5s,以确保子线程能够运行完毕,
   之后调用ExitThread(0)将所有线程撤销。

在这里插入图片描述
在这里插入图片描述

实验二总结:
   在该实验中,创建了Th1 Th2 Th3三个子线程,为了能清楚地看到线程的运行情况,在主线程创建了子线程之后,
   打印“I'm eatting apples”以确保能够直观的看出运行情况,
   之后调用ExitThread(0)将所有线程撤销。
   ExitThread(0)的使用:
   	void eatApple(int number){
	Sleep((3 - number)*1000);
	printf("I'm eatting #%d apples.\n",number);
		while(1){
			printf("#%d is exiting.\n\n",number);
			ExitThread(0);
		}
	}
PS:视频中用的是这种方法,但是我在学习文档中看到ExitThread(0)表示要撤销进程中的所有线程。所以我没用视频中的方法,直接在代码后面加了“ExitThread(0);”语句。

在这里插入图片描述
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_44919455/article/details/105629695

智能推荐

java计算机毕业设计基于微信小程序的外卖点餐平台【附源码+远程部署+程序+mysql】-程序员宅基地

文章浏览阅读899次,点赞21次,收藏7次。对于餐饮业者来说,该平台能够拓宽其服务范围,利用微信庞大的用户基础,增加曝光率和交易机会,同时通过数据分析优化菜品结构和服务流程,提升经营效率。在技术上,采用Java语言进行后台开发可以保证平台的稳定运行和数据的安全处理,且Java生态的丰富性为平台的后续扩展和维护提供了便利。从教育角度来看,这样的项目能够让计算机专业的学生将理论知识与实际应用相结合,锻炼其解决实际问题的能力,为他们未来的职业发展奠定坚实的基础。微信小程序作为一种新型的应用形式,因其易用性和广泛的用户基础,成为了商家与顾客互动的重要渠道。

方正台式计算机初始bios密码,方正电脑刷BIOS的方法-程序员宅基地

文章浏览阅读2.4k次。方正电脑刷BIOS的方法作者:小龙博客 2013年08月24日  7条评论 分类:电脑技巧 系统 软件如果你有一台方正文祥E630,想装第一步、去找个别的机器上的硬盘,来接到你弄坏的这台上边,硬盘保护卡自动会失效的。建议那块硬盘上装有系统,推荐ghostXP(开机会提示安装保护卡,按ESC跳过就可)。如果找不到别的硬盘,可以试一下用U盘或光盘进PE系统备份和刷BIOS。第二步、在从新装硬盘启动并进..._方正电脑bios默认密码

PHP之CURL实现含有验证码的模拟登录_php curl 验证码 登录-程序员宅基地

文章浏览阅读7.6k次,点赞7次,收藏25次。博主最近在为学校社团写一个模拟登录教务系统来进行成绩查询的功能,语言当然是使用PHP啦,原理是通过php数据传输神器—curl扩展,向学校教务系统发送请求,通过模拟登录,获取指定url下的内容。 在开始实验之前有必要对curl扩展进行一下认识_php curl 验证码 登录

XHTML 1.0规范-程序员宅基地

文章浏览阅读112次。XHTML 1.0规范链接:http://www.w3.org/TR/Markup/ ..._xhtml1.0的基本规范

计算机二级桌面,2016计算机二级《MS OFFICE》模拟试题及答案-程序员宅基地

文章浏览阅读380次。2016计算机二级《MS OFFICE》模拟试题及答案1、在因特网浏览中,鼠标指针在网页链接上的形状是__C__A、左上箭头 B、左上箭头加上等待状态C、手型 D、手型加上拒绝浏览圆圈2、在用自己的计算机浏览WEB网的过程中,如果你发现自己喜欢的网页并希望以后多次访问,最好的方法是把这个页面地址__D__A、用Word文件保存下来 B、记忆下来C、用笔抄写到笔记本上 D、放到收藏夹中3、在桌面上创..._在资源管理器中文件排列不可以按()显示。a.名称b.类型c.文件大小d.图标大小d

Spring : 使用 jdbcTemplate_value="${jdbc.driver}-程序员宅基地

文章浏览阅读143次。1.jdbc.properteis : 参数配置文件jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql:///spring1jdbc.username=rootjdbc.password=root2. applicationContext.xml : 核心配置文件<?xml version="1.0"..._value="${jdbc.driver}

随便推点

配置Opencv的遇到的一些麻烦.._opencvcore_240-程序员宅基地

文章浏览阅读1.2k次。本来以为装个库很简单的..结果按照网上的流程走还是出了很多错误.这里就总结一下吧.方便后人... 1.VC6.0只能安装2.0以下的opencv的版本.刚开始我不知道有这个情况..所以自然出错了.下了个2.44的弄去配置,发现很多文件名和位置都变动了.于是下了个2.2的.配置算是配置好了,但是一编译还是出错.如果是cpp文件会提示error C2535: '__thiscall_opencvcore_240

基于STM32F103单片机的指南针电子罗盘方位显示原理图PCB程序设计_stm32如何画一个随着角度变化而变化的指南针-程序员宅基地

文章浏览阅读4.8k次,点赞10次,收藏58次。硬件电路的设计(末尾附文件)本系统由STM32F103C8T6单片机、LCD1602液晶显示、GY-271模块及电压组成。1、上电先进行数据校准,刚上电,液晶没有出现显示的情况下:以传感器为中心顺时针缓慢旋转一周;然后以传感器为轴心缓慢翻转一周。2、校准后液晶开始显示,指南针模块获取位置信息,并在液晶LC1602上显示方向和角度。系统硬件系统分析设计1、STM32单片机核心电路设计STM32系列处理器是意法半导体ST公司生产的一种基于ARM 7架构的32位、支持实时仿真和跟踪的微控制器。选择此_stm32如何画一个随着角度变化而变化的指南针

数据库作业7:SQL练习4 - SELECT(连接查询、嵌套查询)_select 子查询 练习-程序员宅基地

文章浏览阅读4.1k次,点赞5次,收藏25次。数据查询2—连接查询:同时涉及两个以上的表的查询连接条件:用来连接两个表的条件[<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2>连接字段:连接条件中的列名称(注意:连接字段类型必须是可比的,但名字不必相同)连接查询—(1)等值与非等值连接查询:等值连接:连接运算符为=(对比关系代数中的等值连接) 【例3...._select 子查询 练习

SCI一区 | Matlab实现PSO-TCN-BiGRU-Attention粒子群算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测-程序员宅基地

文章浏览阅读1.6k次,点赞32次,收藏14次。SCI一区 | Matlab实现PSO-TCN-BiGRU-Attention粒子群算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测_pso-tcn-bigru-attention

Spring MVC中Controller如何获取Form表单提交的数据_提交表单 controller 获取 id值-程序员宅基地

文章浏览阅读2.2w次,点赞5次,收藏26次。表单提交的数据也就是请求数据,分为Get和Post两种方式提交。Controller中有三种方式获取表单数据: Controller的方法,添加HttpServletRequst类型入参,通过HttpServletRequst.getParameter()获取请求数据 Controller的方法,添加对应表单字段name的参数,有几个表单字段就添加多少个对应的入参,如下 ..._提交表单 controller 获取 id值

vue2 实现日历组件,包含新增日程_vue 日历表插件-程序员宅基地

文章浏览阅读1.9k次。实现的最终效果:模板 html 部分js 部分css 部分_vue 日历表插件