首页 > 系统相关 >操作系统实验之Windows中的线程与线程同步现象

操作系统实验之Windows中的线程与线程同步现象

时间:2024-10-22 18:48:22浏览次数:8  
标签:同步 操作系统 Windows ++ int 线程 cs 实验

一、实验目的

1.掌握Windows中线程的操作。

2.熟悉线程不同步时的现象及环境因素。

3.掌握一种同步对象的使用。

二、实验理论基础及教材对应关系

1.线程和线程不同步的认识。

2.线程间的同步和通信。

3.本实验内容主要对应于操作系统教材第2章中关于线程的各节。

三、实验内容与步骤

1.定义全局变量 int i = 0; 初始值置为 0。

2.创建两个线程,一个对 i 执行加 1 操作,另一个对 i 执行减 1 操作。两个线程执行相同的次数。

显然,正常情况下,i 的仍然保持为 0。

#include <stdio.h>

#include <windows.h>

#define MaxCount 9000000  // 循环次数要很大,可多次尝试一些值

DWORD __stdcall fun1( LPVOID p1)

{

for( int j =0 ;j < MaxCount;j++){

i++;

}

return 0;

}

DWORD __stdcall  fun2( LPVOID p1)

{

for( int j =0 ;j < MaxCount;j++){

i--;

}

return 0;

}

3.观察两个线程执行后的情况,可以发觉最后 i 的值不一定是 0, 有时是很大的正数,有时是很大的负数,这就是多个线程在操作同一个变量 i时,未同步时带来的严重问题。

    还应该了解,在多个线程操作共享的变量时,才需要考虑同步问题。

4.给这两个线程加上同步代码,再来观察对 i 值的影响。步骤2的函数稍微改动即可:

CRITICAL_SECTION cs;

DWORD __stdcall fun1( LPVOID p1)

{

for( int j =0 ;j < MaxCount;j++){

::EnterCriticalSection(&cs);

i++;

::LeaveCriticalSection(&cs);

}

}

DWORD __stdcall  fun2( LPVOID p1)

{

for( int j =0 ;j < MaxCount;j++){

::EnterCriticalSection(&cs);

i--;

::LeaveCriticalSection(&cs);

}

}

加入的同步代码的两个线程,无论如何执行,i 的值总是 0 ,结果是正确的。

5.主函数的写法

int main()

{

DWORD id1,id2;

HANDLE hThread[2];

::InitializeCriticalSection(&cs);

hThread[0] = ::CreateThread(0,0,fun1,0,0,&id1);

hThread[1] = ::CreateThread(0,0,fun2,0,0,&id2);

::WaitForMultipleObjects(2,hThread,1,INFINITE);

printf("i = %d\n",i);

::DeleteCriticalSection(&cs);

getchar();

return 0;

}

实验分析

未同步的情况:

在不包含同步代码的版本中(即原始版本的 fun1 和 fun2 函数),两个线程会并发地修改全局变量 i。

由于没有同步机制,可能会出现竞态条件,即两个线程可能同时尝试修改 i 的值,导致 i 的最终值不确定。

实验结果可能显示 i 的值为很大的正数、很大的负数或零附近的某个值,这取决于线程调度的具体方式和时机。

同步的情况:

在包含同步代码的版本中,使用了临界区来确保对 i 的访问是互斥的。

这意味着在任何时刻,只有一个线程可以进入临界区并执行加 1 或减 1 操作。

由于加 1 和减 1 操作的数量相等,且这些操作是同步进行的,因此最终 i 的值将始终为 0。

实验结果将一致地显示 i = 0。

实验结论:

本实验展示了多线程编程中同步机制的重要性。

当多个线程需要访问和修改共享资源时,必须使用适当的同步机制来避免竞态条件和不确定的行为。

临界区是一种有效的同步机制,可以确保对共享资源的互斥访问。

标签:同步,操作系统,Windows,++,int,线程,cs,实验
From: https://blog.csdn.net/m0_74107848/article/details/143161792

相关文章

  • 国产CPU与操作系统:信创核心技术的中坚力量
    信创与国产化的技术支柱在中国推动信息技术应用创新(信创)的过程中,CPU和操作系统是其不可或缺的核心组成部分。国产化的CPU和操作系统为中国的信息安全和自主可控提供了坚实的技术保障,逐步实现了从政府到企业领域的信息技术替代。六大国产CPU门派:自主创新的力量中国在推动CPU......
  • Windows server 2019 安装vscode
    以下是在WindowsServer2019上安装VisualStudioCode(VSCode)的步骤:一、下载VSCode安装程序打开浏览器,访问VisualStudioCode官方网站(VisualStudioCode-CodeEditing.Redefined)。在官网首页,找到“DownloadforWindows”按钮并点击,下载适合Windows系统的......
  • 线程池实现原理及实践
    线程池的总体设计ThreadPoolExecutor实现的顶层接口是Executor,顶层接口Executor提供了一种思想:将任务提交和任务执行进行解耦。用户无需关注如何创建线程,如何调度线程来执行任务,用户只需提供Runnable对象,将任务的运行逻辑提交到执行器(Executor)中,由Executor框架完成线程的调配......
  • 揭秘Windows Anytime Upgrade的守护神:windowsanytimeupgradecpl.dll及缺失应对秘籍
    在Windows操作系统的世界里,有一个不为人知但至关重要的文件——windowsanytimeupgradecpl.dll。这个文件是WindowsAnytimeUpgrade功能的守护者,它负责管理和执行Windows版本的升级过程,确保用户能够顺利地从低版本升级到更高版本的Windows系统。WindowsAnytimeUpgrade的守......
  • Windows系统lua51.dll文件丢失?Windows用户必看lua51.dll文件丢失的解决之道
    当Windows系统中的lua51.dll文件丢失时,可能会导致依赖它的软件或游戏无法正常运行。以下是一些针对Windows用户解决lua51.dll文件丢失问题的详细步骤:一、使用系统文件检查器(SFC)打开管理员命令行:按下Windows键+X,选择“命令提示符(管理员)”或“WindowsPowerShell(管理员)”。运......
  • Windows Installer核心clbcatq.dll丢失?找回Windows Installer关键组件clbcatq.dll的修
    在Windows操作系统中,clbcatq.dll是WindowsInstaller服务的一个关键组件,它负责处理与安装、配置和删除WindowsInstaller包(.msi文件)相关的任务。如果clbcatq.dll文件丢失或损坏,可能会导致WindowsInstaller无法正常工作,进而影响软件的安装、更新和卸载。如果你遇到了clbcatq.dl......
  • 鸿蒙Flutter实战:02-Windows环境搭建踩坑指南
    鸿蒙Flutter实战:02-Windows环境搭建踩坑指南环境搭建1.下载FlutterSDK,配置环境变量鸿蒙FlutterSDK需要在Gitee下载。目前建议下载dev分支代码。需要配置以下用户变量注意鸿蒙开发需要安装Java和配置相关变量#fluttersdk镜像FLUTTER_STORAGE_BASE_URL=https://s......
  • Django for beginner for windows
    Setupdjangoprojectstep1:createafolderforprojectandswitchtothefolderinterminal.step2:createavirtualenvironment:python-mvenvvirtual_environment_namestep3:activatethevirtualenvironment:virtual_environment_name\Scripts\acti......
  • .NET 隐藏/自定义windows系统光标
    本文介绍如何操作windows系统光标。正常我们设置/隐藏光标,只能改变当前窗体或者控件范围,无法全局操作windows光标。接到一个需求,想隐藏windows全局的鼠标光标显示,下面讲下如何操作 先了解下系统鼠标光标,在鼠标属性-自定义列表中可以看到一共有13种类型,对应13种工作状态:操作系......
  • 操作系统中的文件操作
    当我们打开电脑,通过资源管理器查看文件时,可以看到各种属性:文件的名字、大小、创建时间等等。这些文件以一种直观的方式呈现在我们眼前,它们存储在外部存储器中,如硬盘或者SSD中。然而,当我们自己写程序操作这些文件时,这种简单的可视化就不够了。那么,如何用代码和这些文件进行交互?如何......