Win32和c++11多线程

news2024/10/7 20:32:23

Win32和c++11多线程

  • 一、概念
    • 1.线程的特点
      • 线程内核对象
      • 线程控制块
      • 线程是独立调度和分派的基本单位
      • 共享进程的资源
    • 2.线程的上下文切换
      • 引起上下文切换的原因
    • 3.线程的状态
  • 二、Windows多线程API
    • 1.CreateThread创建线程
    • 2.获取线程ID
    • 3.关闭线程句柄
    • 4.挂起线程
    • 5.恢复线程
    • 6.休眠线程的执行
    • 7.WaitForSingleObject
    • 8.终止线程
    • 9.获取线程结束码
    • 10.WaitForMultipleObjects
    • 11.\_beginthread和\_endthread
      • CreateThread不安全
      • _beginthread
      • _endthread
  • 三、多线程模拟火车站售票
    • 1.介绍
    • 2.实现
    • 3.为什么会出现卖出了第0张票?
  • 四、多线程之间的同步和互斥
    • 1.临界区
      • 临界区结构对象
      • 初始化临界区
      • 进入和离开临界区
      • 尝试进入临界区
      • 区别
      • 删除临界区
    • 2.线程死锁
      • 死锁产生的必要条件
    • 3.信号量
      • 临界区与信号量对比
      • 相关API
        • (1)创建信号量
        • (2)P操作
        • (3)V操作
      • 实现进程或线程只有一个实例
    • 4.互斥量mutex
      • 相关API
        • (1)创建互斥量
        • (2)获得互斥量
        • (3)释放互斥量
      • 示例
      • 利用互斥量实现进程只有一个实例
    • 5.事件Event
      • 有信号状态和无信号状态
      • 相关API
        • (1)创建事件
        • (2)把指定的事件对象设置为有信号状态
        • (3)把指定的事件对象设置为无信号状态
        • (4)等待事件对象的句柄
      • 自动重置事件
      • 手动重置事件
      • 实现进程只有一个实例
    • 6.PV操作
      • 生产者消费者问题
    • 7.总结
  • 五、线程本地存储
    • 1.静态TLS
    • 2.动态TLS
  • 六、多线程间的消息通讯
    • 示例:一个线程向另一个线程发送消息
  • 七、C++11多线程

一、概念

进程要想执行任务,必须得有线程,线程是进程的基本执行单元,一个进程的所有任务都在线程中执行。

1.线程的特点

线程内核对象

image-20240605145804417

线程控制块

image-20240605150218335

线程是独立调度和分派的基本单位

image-20240605150311558

共享进程的资源

image-20240605150741306

2.线程的上下文切换

image-20240605150530459

引起上下文切换的原因

image-20240605150633369

3.线程的状态

image-20240605150910902

二、Windows多线程API

头文件#include<Windows.h>

1.CreateThread创建线程

image-20240605152131609

image-20240516142623087

参数说明:

image-20240516142832814

image-20240516142905778

image-20240516142916364

image-20240605153127463

image-20240605153448758

image-20240605153651291

线程的句柄是一块地址,线程ID可以用GetCurrentThreadId()函数获得。

2.获取线程ID

image-20240605153821261

3.关闭线程句柄

image-20240605154021018

关闭句柄后线程还会继续执行。

image-20240605154117019

4.挂起线程

  • image-20240516160333721

5.恢复线程

  • image-20240516160345244

6.休眠线程的执行

image-20240605154338760

image-20240516160456113

image-20240516160544829

image-20240516160630172

7.WaitForSingleObject

等待一个内核对象变为已通知状态。这个函数常用于线程同步,确保一个线程在继续执行之前等待某个事件(如线程结束、互斥体释放、信号量达到等)。

image-20240516161052721

image-20240605154827878

未通知状态:该句柄关联的线程未结束,仍在执行。

已通知状态:该句柄关联的线程执行结束。

参数:

  • hHandle:等待的对象的句柄。这个句柄可以是各种同步对象,如事件、互斥体、信号量、进程或线程。
  • dwMilliseconds:超时时间,以毫秒为单位。如果设置为 INFINITE,表示无限等待,直到对象进入信号状态。

返回值:

WaitForSingleObject 返回一个 DWORD 值,表示函数的结果。常见的返回值包括:

  • WAIT_OBJECT_0:指定的对象已进入信号状态。
  • WAIT_TIMEOUT:等待超时,指定的对象在超时时间内未进入信号状态。
  • WAIT_FAILED:函数调用失败。可以通过调用 GetLastError 函数获取扩展错误信息。

image-20240516165705270

image-20240516165851008

8.终止线程

image-20240605160913185

image-20240605160954068

image-20240605161127385

9.获取线程结束码

image-20240605161229123

image-20240605161524581

image-20240605161757840

10.WaitForMultipleObjects

image-20240605162649735

参数说明:

image-20240605162711186

image-20240605162742271

image-20240605164709416

image-20240605164737174

image-20240605164834379

image-20240605164940970

11._beginthread和_endthread

CreateThread不安全

image-20240605174352416

image-20240605174419176

image-20240605174437446

_beginthread

image-20240605174503773

参数说明:

image-20240605174520555

返回值:

image-20240605174532687

image-20240605174623102

_endthread

image-20240605174725854

image-20240605174658871

三、多线程模拟火车站售票

1.介绍

image-20240605174832615

2.实现

image-20240605180907553

3.为什么会出现卖出了第0张票?

image-20240605181106184

四、多线程之间的同步和互斥

image-20240605181300485

image-20240605181336669

1.临界区

image-20240605181421442

临界区结构对象

image-20240605182407927

image-20240605183747657

初始化临界区

image-20240605182449993

image-20240605183811888

进入和离开临界区

image-20240605182512368

image-20240605184010452

如果这样加锁,那么只要有一个线程进入临界区,除非所有票卖完,否则不会释放临界区。

image-20240605184058320

如果这样加锁,又会出现卖出第0张票的情况。

image-20240605184227886

最后这种情况,修改代码,在进入临界区后再次判断,可以避免上述情况。

尝试进入临界区

image-20240605182543787

image-20240605184352148

区别

image-20240605182602698

删除临界区

image-20240605183856780

2.线程死锁

死锁产生的必要条件

image-20240606113014747

image-20240606115219850

3.信号量

临界区与信号量对比

image-20240606115405216

  • 临界区

    • 用于保护共享资源的代码块,确保在同一时间只有一个线程能够执行该代码块。

    • 通常用于同一进程内的线程同步

  • 信号量

    • 是一种更通用的同步机制,允许多个线程同时访问一定数量的共享资源。

    • 可以用于进程间同步(IPC)

image-20240606115744071

image-20240606115455413

image-20240606143735532

相关API

(1)创建信号量

image-20240606143849354

(2)P操作

image-20240606145923577

(3)V操作

image-20240606143907632

image-20240606153314506

image-20240606153340224

image-20240606153401451

实现进程或线程只有一个实例

image-20240606150021871

虽然每个进程有自己的地址空间,但命名对象(如命名信号量、命名互斥体等)是在系统范围内共享的。这意味着即使进程有各自的地址空间,命名对象在创建时会注册在操作系统的命名空间中,其他进程可以通过同样的名字访问这些对象。

在 Windows 操作系统中,命名对象(包括信号量、互斥体、事件等)在系统命名空间中共享。也就是说,当一个进程创建一个命名信号量时,操作系统会将该信号量注册在全局命名空间中。其他进程如果尝试创建或打开同名的信号量,就可以访问到这个信号量。

image-20240606153815475

image-20240606153800739

4.互斥量mutex

image-20240606154006810

相关API

(1)创建互斥量

image-20240606154406949

bInitialOwner:指定调用线程是否在互斥对象的初始状态下获得所有权。如果这个值为 TRUE,调用线程在互斥对象创建成功后立即获得所有权;否则,互斥对象的初始状态为非信号状态。

(2)获得互斥量

image-20240606154520926

(3)释放互斥量

image-20240606154503036

示例

image-20240606160347987

利用互斥量实现进程只有一个实例

image-20240606155545495

5.事件Event

image-20240606160435449

有信号状态和无信号状态

在 Windows 操作系统中,事件对象用于线程同步,其状态可以是“有信号”(signaled)或“无信号”(nonsignaled)。这两种状态用于控制线程的执行,具体如下:

  • 当事件对象处于有信号状态时,所有等待该事件的线程都将被解除阻塞,并继续执行。这意味着事件发生了,等待的线程可以继续进行它们的工作。
  • 当事件对象处于无信号状态时,所有等待该事件的线程都将被阻塞,直到事件对象的状态变为有信号。这意味着事件尚未发生,等待的线程需要等待,直到事件发生。

事件对象可以分为两种类型:自动重置事件(auto-reset event)和手动重置事件(manual-reset event)。这两种类型的事件对象在状态变更和重置机制上有所不同。

  • 当事件对象处于有信号状态时,等待的线程将被解除阻塞,然后事件对象自动重置为无信号状态。如果有多个线程在等待事件,只有一个线程会被解除阻塞。
  • 当事件对象处于有信号状态时,所有等待的线程将被解除阻塞,并且事件对象保持有信号状态,直到显式调用 ResetEvent 函数将其状态重置为无信号状态。

相关API

(1)创建事件

image-20240606160515420

image-20240606160613597

image-20240606161644280

(2)把指定的事件对象设置为有信号状态

image-20240606161928805

(3)把指定的事件对象设置为无信号状态

image-20240606161939112

(4)等待事件对象的句柄

image-20240606162036761

自动重置事件

image-20240606172017213

image-20240606172030196

手动重置事件

image-20240606172214513

image-20240606172224982

实现进程只有一个实例

image-20240606162907008

6.PV操作

image-20240606163338590

image-20240606163359361

image-20240606163453771

生产者消费者问题

image-20240606173853045

image-20240606183820827

image-20240606183350204

image-20240606183837525

image-20240606183847366

image-20240606183223250

7.总结

image-20240606175903298

image-20240606175918058

五、线程本地存储

image-20240606183924354

image-20240606183959998

1.静态TLS

image-20240606184019678

image-20240606184640153

image-20240606193139905

image-20240606193224677

2.动态TLS

image-20240606184653794

image-20240606184714558

image-20240606184740531

image-20240606184753825

image-20240606184810198

image-20240606193612434

image-20240606193715668

六、多线程间的消息通讯

image-20240606185506675

image-20240606185538495

image-20240606185626726

image-20240606185657092

image-20240606185723925

image-20240606185747919

image-20240606185832891

image-20240606185851690

image-20240606185905585

示例:一个线程向另一个线程发送消息

image-20240606201823849

image-20240606201936056

使用PeekMessage写法如下:
在这里插入图片描述

七、C++11多线程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1795775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

GAT1399协议分析(二)--注册流程分析

一、官方流程说明 二、官方流程解析 1 : 发起方向接收方发送注册 HTTP POST 请求/VIID/System/Register。 2: 接收方向发送方发送响应401 Unauthorized, 并在响应的消息头 WWW-Authenticate 字段中给 出适合发送方的认证机制和参数。 3: 发起方重新向接收方发送注册 HTTP POST…

谷歌创新框架:从非结构化数据,实现多模态学习

看、听、说的多模态已成为主流大模型的重要功能之一。但在数据爆炸时代&#xff0c;大模型学习文本类的结构化数据相对还好一些&#xff0c;但要去学习视频、音频、图片等非结构化数据非常困难。 目前&#xff0c;从结构化和非结构化数据实现多模态学习&#xff0c;会随着模态…

【Linux】查看进程在哪个CPU上运行

当前服务器是多核&#xff0c;在进行性能压测时&#xff0c;需要除了要观测全局的CPU使用率&#xff0c;对于单进程单线程往往需要在一个cpu上运行&#xff0c;那如何查看进程在哪个CPU上运行呢&#xff1f; 方法一&#xff1a;taskset taskset命令主要是用来检索或设置一个处…

IO进程线程(九)线程的同步 进程间通信

文章目录 一、 线程的同步&#xff08;一&#xff09;无名信号量sem1. 定义和初始化2.获取信号量3.释放信号量4. 销毁5. 使用示例 &#xff08;二&#xff09;条件变量1. 定义和初始化2. 获取条件变量3. 释放条件变量4. 销毁条件变量 二、进程间通信&#xff08;一&#xff09;…

yum进阶——配置yum源

一、yum概述 yum的主要作用 解决依赖关系 自动安装 自动升级 各个系统中的安装软件服务 CentOS7 &#xff1a;yum -y 安装 rpm包 CentOS8 &#xff1a;dnf&#xff08;yum的升级版&#xff09;&#xff0c; Ubantu(22.04) &#xff1a;apt -y 安装&#xff0c;安装源为/…

【Python报错】已解决ModuleNotFoundError: No module named ‘packaging’

成功解决“ModuleNotFoundError: No module named ‘packaging’”错误的全面指南 在Python编程中&#xff0c;遇到ModuleNotFoundError: No module named packaging这样的错误&#xff0c;通常意味着你的Python环境中缺少名为packaging的模块&#xff0c;或者该模块没有被正确…

sing-task message

文章目录 1.起因2.查因过程2.1 定位job2.2 定位sql text2.3 定位db_link2.4 测试dblink2.5 tnsping host2.6 检查host信息2.7检查网路状况 3.处置办法&#xff1a;4.结论 1.起因 在巡查长事务时&#xff0c;有两个事务执行了很长时间没有完成 SELECT SE.SID,SE.SERIAL#,to_ch…

CEC2017(Python):五种算法(SSA、RFO、OOA、PSO、GWO)求解CEC2017

一、5种算法简介 1、麻雀搜索算法SSA 2、红狐优化算法RFO 3、鱼鹰优化算法OOA 4、粒子群优化算法PSO 5、灰狼优化算法GWO 二、CEC2017简介 参考文献&#xff1a; [1]Awad, N. H., Ali, M. Z., Liang, J. J., Qu, B. Y., & Suganthan, P. N. (2016). “Problem defin…

gitee和github的协同

假设gitee上zhaodezan有一个开发库&#xff0c;但是从andeyeluguo上拉取最新的&#xff08;从github上同步过来最新的&#xff09; git remote add dbgpt_in_gitee https://gitee.com/andeyeluguo/DB-GPT.git remote -v git pull --rebase dbgpt_in_gitee main 有冲突可能需要…

前端工程化工具系列(九)—— mddir(v1.1.1):自动生成文件目录结构工具

mddir 是一个基于项目目录结构动态生成 Markdown 格式目录结构的工具&#xff0c;方便开发者在文档中展示文件和文件夹的组织结构。 1. 安装 全局安装改工具&#xff0c;方便用于各个项目。 pnpm i -g mddir2. 使用 在想要生成目录接口的项目内打开命令行工具&#xff0c;输…

【漏洞复现】用友NC downCourseWare 任意文件读取漏洞

0x01 产品简介 用友NC是一款企业级ERP软件。作为一种信息化管理工具&#xff0c;用友NC提供了一系列业务管理模块&#xff0c;包括财务会计、采购管理、销售管理、物料管理、生产计划和人力资源管理等&#xff0c;帮助企业实现数字化转型和高效管理。 0x02 漏洞概述 用友NC …

上市即交付,比亚迪秦L DM-i万人交车暨千媒众测开营

6月6日&#xff0c;“引领中级 开创油耗2时代”秦L DM-i万人交车暨千媒众测开营仪式在比亚迪大本营深圳盛大举行。 众多车主代表亲临现场&#xff0c;与全国各地的比亚迪4S店千店联动&#xff0c;将秦L DM-i全国交付推向新的高潮。发布即量产&#xff0c;上市即交付&#xff0…

【NLP】2、大语言模型综述

一、背景和发展历程 大语言模型四个训练阶段&#xff1a; 预训练&#xff1a; 利用海量的训练数据&#xff0c;包括互联网网页、维基百科、书籍、GitHub、 论文、问答网站等&#xff0c;构建包含数千亿甚至数万亿单词的具有多样性的内容。利用由数千块高性能 GPU 和高速网络组成…

【图像处理与机器视觉】XJTU期末考点

题型 选择&#xff1a;1 分10 填空&#xff1a;1 分15 简答题&#xff08;也含有计算和画图&#xff09;&#xff1a;10 分*4 计算题&#xff1a;15 分20 分 考点 选择题&#xff08;部分&#xff09; 数字图像处理基础 p(x,y),q(s,t)两个像素之间的距离由公式&#xff1a…

HBuilderX打包uni-app项目成安卓app

目录 1、下载Android 离线SDK 2、Android Studio导入工程 3、生成签名 3.1、进入到jdk bin目录下&#xff0c;输入cmd执行命令keytool -genkey -alias wxsalias -keyalg RSA -keysize 2048 -validity 36500 -keystore wxs.keystore 生成签名 3.2、查看签名密钥keytool -lis…

C语言实现教学计划编制问题,Dev C++编译器下可运行(240606最新更新)

背景&#xff1a; 问题描述 大学的每个专业都要编制教学计划。假设任何专业都有固定的学习年限&#xff0c;每学年含两学期&#xff0c; 每学期的时间长度和学分上限都相等。每个专业开设的课程都是确定的&#xff0c;而且课程的开设时间的安排必须满足先修关系。每个课程的先…

最优化练习题

def f(x):return x*x-4*x5 a0,b01,31、均匀搜索 令 δ ( b 0 − a 0 ) / N , a i a 0 i δ , i 1 , 2 , 3 \delta(b_0-a_0)/N,a_ia_0i\delta,i1,2,3 δ(b0​−a0​)/N,ai​a0​iδ,i1,2,3 while b0-a0>0.1:anp.linspace(a0,b0,5)for i in range(1,4):if f(a[i-1])>f…

宝兰德受邀出席第八届丝绸之路网络安全论坛

近日&#xff0c;2024第八届丝绸之路网络安全论坛在陕西宾馆会议中心成功举办&#xff0c;本次论坛以“汇聚万千智慧 夯实安全堤坝”为主题&#xff0c;由主论坛及密码技术与密评、教育行业网络安全、卫健行业网络安全三个平行分论坛组成&#xff0c;论坛邀请业内专家学者、企业…

Pinia(三): 了解和使用state

1.state state 就是我们要定义的数据, 如果定义 store 时传入的第二个参数是对象, 那么 state 需要是一个函数, 这个函数的返回值才是状态的初始值.这样设计的原因是为了让 Pinia 在客户端和服务端都可以工作 官方推荐使用箭头函数(()>{ })获得更好的类型推断 import { de…

如何在Windows 10和11上修复DISM错误87?这里提供办法

​在电脑上运行DISM命令时,是否收到“错误代码87”消息?这是一个非常常见的错误,你可以轻松地修复它。我们将向你展示在Windows 11或Windows 10计算机上解决此问题的多种方法。 确保键入正确的命令 运行DISM命令时出现错误代码87的最常见原因是键入的命令不正确。你可能添…