方法阻塞的解决方案之一

1、简单使用

一个h一个cpp文件 

#pragma once
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <string>class Person {public:struct dog {std::string name;int age;};public:void a(std::atomic<bool>& running, int param1, double param2, const std::string& param3);void startA(int param1, double param2, const std::string& param3);
};

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <string>
#include "osg.h"void Person::a(std::atomic<bool>& running, int param1, double param2, const std::string& param3) {std::cout << "Function a started with params " << param1 << ", " << param2 << ", " << param3 << "." << std::endl;// 模拟耗时操作while (running) {// 执行一些操作}std::cout << "Function a ended." << std::endl;
}void Person::startA(int param1, double param2, const std::string& param3) {std::atomic<bool> running(true);// 创建并启动线程std::thread thread_a(&Person::a, this, std::ref(running), param1, param2, param3);std::this_thread::sleep_for(std::chrono::seconds(10));if (running.load()) {std::cout << "stop" << std::endl;running = false;}// 等待线程完成执行if (thread_a.joinable()) {thread_a.join();}
}int main() {Person person;person.startA(42, 3.14, "Hello");// ... 其他代码 ...return 0;}

2、方法A中存在引用

错误示例:

将sum执行的数据保存下来

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <string>
#include "osg.h"void Person::a(std::atomic<bool>& running, int& sum, double param2) {std::cout << "Function a started with params " << sum << ", " << param2 << std::endl;// 模拟耗时操作while (running) {// 执行一些操作for (int i = 0; i < 10000000; i++) {sum = i;}}std::cout << "Function a ended." << std::endl;
}void Person::startA(int param1, double param2, const std::string& param3) {for (int i = 0; i < 2; i++) {int sum = 0;std::atomic<bool> running(true);// 创建并启动线程std::thread thread_a(&Person::a, this, std::ref(running), sum, param2);std::this_thread::sleep_for(std::chrono::seconds(5));if (running.load()) {std::cout << "stop" << std::endl;running = false;}// 等待线程完成执行if (thread_a.joinable()) {thread_a.join();std::cout << "等待线程完成执行" << std::endl;}std::cout << "sum: " <<sum<< std::endl;}std::cout << "任务结束" << std::endl;}
int main() {Person person;person.startA(42, 3.14, "Hello");// ... 其他代码 ...return 0;
}

编译都过不去

正确示例:

 只修改一句

        std::thread thread_a(&Person::a, this, std::ref(running), std::ref(sum), param2);
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <string>
#include "osg.h"void Person::a(std::atomic<bool>& running, int& sum, double param2) {std::cout << "Function a started with params " << sum << ", " << param2 << std::endl;// 模拟耗时操作while (running) {// 执行一些操作for (int i = 0; i < 1000000000; i++) {sum = i;}}std::cout << "Function a ended." << std::endl;
}void Person::startA(int param1, double param2, const std::string& param3) {for (int i = 0; i < 2; i++) {int sum = 0;std::atomic<bool> running(true);// 创建并启动线程std::thread thread_a(&Person::a, this, std::ref(running), std::ref(sum), param2);std::this_thread::sleep_for(std::chrono::seconds(5));if (running.load()) {std::cout << "stop" << std::endl;running = false;}// 等待线程完成执行if (thread_a.joinable()) {thread_a.join();std::cout << "等待线程完成执行" << std::endl;}std::cout << "sum: " <<sum<< std::endl;}std::cout << "任务结束" << std::endl;}
int main() {Person person;person.startA(42, 3.14, "Hello");// ... 其他代码 ...return 0;
}

3、A方法阻塞时间过长,希望停止

如果Person::a 方法卡住了,那么 if (thread_a.joinable()) { thread_a.join(); } 就阻塞了,std::cout << "sum: " <<sum<< std::endl; 值就得不到了,除非a方法完成了

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <string>
#include "osg.h"void Person::a(std::atomic<bool>& running, int& sum, const double &param2) {std::cout << "Function a started with params " << sum << ", " << param2 << std::endl;// 模拟耗时操作for (int i = 0; i < 10; i++) {std::this_thread::sleep_for(std::chrono::seconds(1));sum = i;}std::cout << "Function a ended." << std::endl;}void Person::startA(int param1, double param2, const std::string& param3) {for (int i = 0; i < 2; i++) {int sum = 0;std::atomic<bool> running(true);// 创建并启动线程std::thread thread_a(&Person::a, this, std::ref(running), std::ref(sum), param2);std::this_thread::sleep_for(std::chrono::seconds(3));if (running.load()) {std::cout << "stop" << std::endl;running = false;}// 等待线程完成执行if (thread_a.joinable()) {thread_a.join();}std::cout << "sum: " <<sum<< std::endl;}std::cout << "任务结束" << std::endl;}
int main() {Person person;person.startA(42, 3.14, "Hello");// ... 其他代码 ...return 0;
}

修改:

在每次循环、处理小任务、遍历某数据 中 进行running判断

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
#include <string>
#include "osg.h"void Person::a(std::atomic<bool>& running, int& sum, const double &param2) {std::cout << "Function a started with params " << sum << ", " << param2 << std::endl;// 模拟耗时操作for (int i = 0; i < 10; i++) {if (!running) break;std::this_thread::sleep_for(std::chrono::seconds(1));sum = i;}std::cout << "Function a ended." << std::endl;}void Person::startA(int param1, double param2, const std::string& param3) {for (int i = 0; i < 2; i++) {int sum = 0;std::atomic<bool> running(true);// 创建并启动线程std::thread thread_a(&Person::a, this, std::ref(running), std::ref(sum), param2);std::this_thread::sleep_for(std::chrono::seconds(3));if (running.load()) {std::cout << "stop" << std::endl;running = false;}// 等待线程完成执行if (thread_a.joinable()) {thread_a.join();}std::cout << "sum: " <<sum<< std::endl;}std::cout << "任务结束" << std::endl;}
int main() {Person person;person.startA(42, 3.14, "Hello");// ... 其他代码 ...return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

笔记本从零安装ubuntu server系统+环境配置

文章目录 前言相关链接ubuntu Server 安装教程屏幕自动息屏关上盖子不休眠MobaXterm外网SSH内网穿透IPV6远程 为什么我要笔记本装Linux为什么要换ubuntu Server版能否连接wifi之后Linux 配置清单总结 前言 之前装了个ubuntu desktop 版&#xff0c;发现没有命令行&#xff0c;…

《HTML 简易速速上手小册》第4章:HTML 的表单与输入(2024 最新版)

文章目录 4.1 表单的基础&#xff08;&#x1f4dd;&#x1f680;&#x1f4ac; 开启沟通的大门&#xff09;4.1.1 表单基础知识点4.1.2 基础示例&#xff1a;创建一个简单的注册表单4.1.3 案例扩展一&#xff1a;创建一个调查问卷4.1.4 案例扩展二&#xff1a;创建一个预订表单…

【01】Linux 基本操作指令

带⭐的为重要指令 &#x1f308; 01、ls 展示当前目录下所有文件&#x1f308; 02、pwd 显示用户当前所在路径&#x1f308; 03、cd 进入指定目录&#x1f308; 04、touch 新建文件&#x1f308; 05、tree 以树形结构展示所有文件⭐ 06、mkdir 新建目录⭐ 07、rmdir 删除目录⭐…

【Java 数据结构】LinkedList与链表

LinkedList与链表 1. ArrayList的缺陷2. 链表2.1 链表的概念及结构2.2 链表的实现 3. LinkedList的模拟实现4.LinkedList的使用4.1 什么是LinkedList4.2LinkedList的使用 5. ArrayList和LinkedList的区别 1. ArrayList的缺陷 上节课已经熟悉了ArrayList的使用&#xff0c;并且…

虚拟机扩容后黑屏卡死解决方法

亲测有效&#xff0c;首先一般是在扩容后黑屏的&#xff0c;现象为开机后看到个横线光标不闪&#xff0c;黑屏&#xff0c;进入不了桌面。原因是硬盘已经满了&#xff0c;所以解决方法就是清理硬盘。所以首先还是要解决登录问题。 开机时按 esc 键进入 GNU GRUB&#xff0c;选择…

windows平台使用tensorRT部署yolov5详细介绍,整个流程思路以及细节。

目录 Windows平台上使用tensorRT部署yolov5 前言&#xff1a; 环境&#xff1a; 1.为什么要部署&#xff1f; 2.那为什么部署可以解决这个问题&#xff1f;&#xff08;基于tensorRT&#xff09; 3.怎么部署&#xff08;只讨论tensorRT&#xff09; 3.0部署的流程 3.1怎…

GoLang和GoLand的安装和配置

1. GoLang 1.1 特点介绍 Go 语言保证了既能达到静态编译语言的安全和性能&#xff0c;又达到了动态语言开发维护的高效率&#xff0c;使用一个表达式来形容 Go 语言&#xff1a;Go C Python , 说明 Go 语言既有 C 静态语言程序的运行速度&#xff0c;又能达到 Python 动态语…

闭包的理解?闭包使用场景

说说你对闭包的理解&#xff1f;闭包使用场景 #一、是什么 一个函数和对其周围状态&#xff08;lexical environment&#xff0c;词法环境&#xff09;的引用捆绑在一起&#xff08;或者说函数被引用包围&#xff09;&#xff0c;这样的组合就是闭包&#xff08;closure&#…

Vite+Vue3使用Vue-i18n笔记

一、下载依赖 vue-i18n yarn add vue-i18n创建存放语言文件的目录 以及配置文件的配置 我是在src/lang 新建index.ts、cn.ts、en.ts以及test文件夹其中再分别新建cn.ts以及en.ts /lang/index.ts 用于导出vue-i18n需要的配置对象 import en from "./en.ts"; import…

无人机在三维空间中的转动问题

前提 这篇博客是对最近一个有关无人机拍摄图像项目中所学到的新知识的一个总结&#xff0c;比较杂乱&#xff0c;没有固定的写作顺序。 无人机坐标系旋转问题 上图是无人机坐标系&#xff0c;绕x轴是翻滚(Roll)&#xff0c;绕y轴是俯仰(Pitch)&#xff0c;绕z轴是偏航(Yaw)。…

开发工具git分支冲突解决

在团队协作的软件开发过程中&#xff0c;Git是一款广泛使用的版本控制系统。然而&#xff0c;当多个开发者同时修改同一文件或代码段时&#xff0c;就会产生分支冲突。解决这些冲突需要仔细的协调和技术知识。本篇博客将介绍Git分支冲突的解决方法&#xff0c;以及开发工具和最…

代码随想录 Leetcode108. 将有序数组转换为二叉搜索树

题目&#xff1a; 代码(首刷自解 2024年1月31日&#xff09;&#xff1a; class Solution { public:TreeNode* recursion(vector<int>& nums, int left, int right) {if (left > right) return nullptr;int mid left (right-left)/2;TreeNode* node new TreeN…