岚皋网站建设/抖音热门搜索关键词

岚皋网站建设,抖音热门搜索关键词,新媒体营销案例ppt,ui设计网站建设是什么朋友们、伙计们,我们又见面了,本期来给大家带来封装线程相关的知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从入门到精通 数据结…

朋友们、伙计们,我们又见面了,本期来给大家带来封装线程相关的知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!

C 语 言 专 栏:C语言:从入门到精通

数据结构专栏:数据结构

个  人  主  页 :stackY、

C + + 专 栏   :C++

Linux 专 栏  :Linux

​ 

目录

引言:

1. 基础框架 

1.1 初步Start接口

1.2 修正后的Start接口

2. Join接口

 2.1 初步测试

3. 添加模版

4. 全部代码


引言:

我们想要通过封装原生线程库的方式来实现一个类似于C++11里面的线程库,这里只是为了来更沉入的学习原生线程库,实现一些基础的功能即可;

我们创建一个mian.cc文件用于测试线程逻辑;

Thread.hpp主要用于封装线程;

Makefile主要实现自动化代码构建。

1. 基础框架 

  • 我们想要封装的线程需要有对应的线程id、线程名、该线程是否运行以及线程所要执行的任务;
  • 线程所需要执行的任务我们需要用函数包装器(functional)
  • 我们想要实现的方法有一个让线程启动起来的方法,还需要有一个等待线程的方法;
  • 后面根据需要添加对应的成员和方法。

Thread.hpp:

先将基础框架搭建出来,后面再慢慢补充所需要的接口以及代码。

1.1 初步Start接口

在Start接口就是用来启动线程,那么在接口设计中就需要先创建进程,在对应的线程执行方法中执行我们预先设计好的func;

这里就需要注意一下线程封装时的细节,我们先来看一下创建线程的接口具体传递的参数:

我们设置的线程执行方法函数的参数只有一个参数,但是因为我们自己设置的ThreadRoutine函数是类内函数,那么类内函数会默认自己带一个this指针,所以这于原始函数设计接口不符,所以我们需要将该函数设置为静态成员函数,然后我们将this指针传递给他,然后通过this指针来调用我们预设的func;

1.2 修正后的Start接口

2. Join接口

在实现Join之前我们可以设置一个查看线程是否运行的接口以及获取线程名的接口,方便后面的测试;

在等待线程这里我们直接使用原生线程库的接口:

我们目前不关心等待的结果;

 2.1 初步测试

上面的代码算是一份非常简单的线程封装代码,那么接下来我们使用main.cc来使用一下我们封装的线程库,因为我们将线程对象化了,所以我们就可以用容器来保存我们的线程,这其实就是一种“先描述,再组织”的过程。

#include <iostream>
#include <unistd.h>
#include <string>
#include <vector>#include "Thread.hpp"
// 设置线程名
std::string GetThreadName()
{static int num = 1;char buffer[64];snprintf(buffer, sizeof(buffer), "Thread-%d", num++);return buffer;
}void Print()
{while(1){std::cout << "hello thread" << std::endl;sleep(1);}
}int main()
{std::vector<Thread> threads;int num = 5;// 创建for(int i = 0; i< num; i++){threads.push_back(Thread(GetThreadName(),Print));}for (auto &t : threads){std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;}// 启动for (auto &t : threads){t.Start();}for (auto &t : threads){std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;}// Joinfor (auto &t : threads){t.Join();}return 0;
}

3. 添加模版

我们想给我们的线程传递参数,所以我们需要添加模版;

整体代码:

#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>template <class T>
using func_t = std::function<void(T)>; // 任务template <class T>
class Thread
{
public:Thread(const std::string &threadname, func_t<T> func, T data): _tid(0), _thread_name(threadname), _isrunning(false), _func(func), _data(data){}// 执行方法static void* ThreadRoutine(void *args){Thread *ts = static_cast<Thread *>(args);ts->_func(ts->_data);return nullptr;}// 启动bool Start(){int n = pthread_create(&_tid, nullptr, ThreadRoutine, this); // 将this指针传递给ThreadRoutineif(n == 0){_isrunning = true;return true;}else return false;}// 等待bool Join(){if (!_isrunning)return false;int n = pthread_join(_tid, nullptr);if (n == 0){return true;}return false;}bool IsRunning(){return _isrunning;}std::string ThreadName(){return _thread_name;}~Thread() {}private:pthread_t _tid;           // 线程idstd::string _thread_name; // 线程名bool _isrunning;          // 线程是否运行func_t<T> _func;             // 线程所执行任务T _data;                   // 传递数据类型
};

4. 全部代码

Makefile

thread:main.ccg++ -o $@ $^ -std=c++11 -lpthread
.PHONY:clean
clean:rm -f thread

main.cc

#include <iostream>
#include <unistd.h>
#include <string>
#include <vector>#include "Thread.hpp"
// 设置线程名
std::string GetThreadName()
{static int num = 1;char buffer[64];snprintf(buffer, sizeof(buffer), "Thread-%d", num++);return buffer;
}void Print(int num)
{while(num--){std::cout << "hello thread num :" << num << std::endl;sleep(1);}
}int main()
{Thread<int> t(GetThreadName(), Print, 5);t.Start();t.Join();// std::vector<Thread> threads;// int num = 5;// // 创建// for(int i = 0; i< num; i++)// {//     threads.push_back(Thread(GetThreadName(),Print));// }// for (auto &t : threads)// {//     std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;// }// // 启动// for (auto &t : threads)// {//     t.Start();// }// for (auto &t : threads)// {//     std::cout << t.ThreadName() << ", is running: " << t.IsRunning() << std::endl;// }// // Join// for (auto &t : threads)// {//     t.Join();// }// Thread ts(Printf, GetThreadName());// std::cout << "is thread running? " << ts.IsRunning() << std::endl;// ts.Start();// std::cout << "is thread running? " << ts.IsRunning() << std::endl;// ts.Join();return 0;
}

Thread.hpp

#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>template <class T>
using func_t = std::function<void(T)>; // 任务template <class T>
class Thread
{
public:Thread(const std::string &threadname, func_t<T> func, T data): _tid(0), _thread_name(threadname), _isrunning(false), _func(func), _data(data){}// 执行方法static void* ThreadRoutine(void *args){Thread *ts = static_cast<Thread *>(args);ts->_func(ts->_data);return nullptr;}// 启动bool Start(){int n = pthread_create(&_tid, nullptr, ThreadRoutine, this); // 将this指针传递给ThreadRoutineif(n == 0){_isrunning = true;return true;}else return false;}// 等待bool Join(){if (!_isrunning)return false;int n = pthread_join(_tid, nullptr);if (n == 0){return true;}return false;}bool IsRunning(){return _isrunning;}std::string ThreadName(){return _thread_name;}~Thread() {}private:pthread_t _tid;           // 线程idstd::string _thread_name; // 线程名bool _isrunning;          // 线程是否运行func_t<T> _func;             // 线程所执行任务T _data;                   // 传递数据类型
};

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

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

相关文章

星越L_三角指示牌及危险警示灯使用

目录 1.打开危险警告灯 2.取出反光背心穿上 3.取出指示牌 4.放置三角指示牌。 1.打开危险警示灯 2.取出反光背心穿上 3.取出指示牌

AI与人的智能,改变一生的思维模型【7】易得性偏差

目录 **易得性偏差思维模型&#xff1a;大脑的「热搜算法」与反操纵指南****病毒式定义&#xff1a;你的大脑正在被「热搜」劫持****四大核心攻击路径与史诗级案例****1. 信息过载时代的「认知短路」****2. 媒体放大器的「恐怖滤镜」****3. 个人经验的「数据暴政」****4. 社交茧…

Jmeter的简单使用

前置工作 确保java8 版本以上jmeter下载路径&#xff08;选择Binaries&#xff09;&#xff1a;https://jmeter.apache.org/download_jmeter.cgi直接解压&#xff0c;找到bin下面的文件&#xff1a;jmeter.bat&#xff08;可选&#xff09;汉化&#xff0c;修改 jmeter.proper…

MyBatis源码分析の配置文件解析

文章目录 前言一、SqlSessionFactoryBuilder1.1、XMLConfigBuilder1.2、parse 二、mappers标签的解析2.1、cacheElement2.1.1、缓存策略 2.2、buildStatementFromContext2.2.1、sql的解析 前言 本篇主要介绍MyBatis源码中的配置文件解析部分。MyBatis是对于传统JDBC的封装&…

golang快速上手基础语法

变量 第一种&#xff0c;指定变量类型&#xff0c;声明后若不赋值&#xff0c;使用默认值0 package mainimport "fmt"func main() {var a int //第一种&#xff0c;指定变量类型&#xff0c;声明后若不赋值&#xff0c;使用默认值0。fmt.Printf(" a %d\n"…

工程实践:如何使用SU17无人机来实现室内巡检任务

阿木实验室最近发布了科研开发者版本的无人机SU17&#xff0c;该无人机上集成了四目视觉&#xff0c;三维激光雷达&#xff0c;云台吊舱&#xff0c;高算力的机载计算机&#xff0c;是一个非常合适的平台用于室内外巡检场景。同时阿木实验室维护了多个和无人机相关的开源项目。…

蓝桥杯嵌入式赛道复习笔记1(led点亮)

前言 基础的文件创建&#xff0c;参赛资源代码的导入&#xff0c;我就不说了&#xff0c;直接说CubeMX的配置以及代码逻辑思路的书写&#xff0c;在此我也预祝大家人人拿国奖 理论讲解 原理图简介 1.由于存在PC8引脚到PC15引脚存在冲突&#xff0c;那么官方硬件给的解决方案…

Linux进程1.0--task_struct

1.硬件&#xff1a;冯诺依曼体系结构&#xff1a; 单个分析&#xff1a;、 数据流向&#xff1a;数据必须先进入输入设备&#xff0c;再到存储器&#xff0c;然后由存储器给控制器&#xff0c;控制器收到以后进行相应的处理后&#xff0c;再传回存储器&#xff0c;存储器最终传…

代码随想录day17 二叉树part05

654.最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums …

宇树人形机器人开源模型

1. 下载源码 https://github.com/unitreerobotics/unitree_ros.git2. 启动Gazebo roslaunch h1_description gazebo.launch3. 仿真效果 H1 GO2 B2 Laikago Z1 4. VMware: vmw_ioctl_command error Invalid argument 这个错误通常出现在虚拟机环境中运行需要OpenGL支持的应用…

通过特征值和特征向量实现的图像压缩和特征提取

前文&#xff0c;我们在学习人工智能的线性代数基础的时候&#xff0c;就了解到&#xff0c;矩阵在人工智能中被广泛使用&#xff0c;接下来我们就从大家非常常见的图像开始&#xff0c;深度理解矩阵在人工智能中的应用。有关线性代数基础的文章可以看的我CSDN:人工智能中的线性…

蓝桥杯2023年第十四届省赛真题-整数删除 暴力-->链表+小根堆

题目来自DOTCPP&#xff1a; 思路&#xff1a; ①每次找到数列中的最小值下标&#xff0c;然后用状态数组st标记它&#xff0c;相当与删除它&#xff0c;之后就不会访问它。 ②对最小值下标左边和右边判断一下&#xff0c;看有没有数字&#xff0c;如果有就把最小值加到两边第…

springboot438-基于SpringBoot的数字化教学资源管理系统(源码+数据库+纯前后端分离+部署讲解等)

&#x1f495;&#x1f495;作者&#xff1a; 爱笑学姐 &#x1f495;&#x1f495;个人简介&#xff1a;十年Java&#xff0c;Python美女程序员一枚&#xff0c;精通计算机专业前后端各类框架。 &#x1f495;&#x1f495;各类成品Java毕设 。javaweb&#xff0c;ssm&#xf…

蓝桥杯刷题——第十五届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组

一、0握手问题 - 蓝桥云课 算法代码&#xff1a; #include <iostream> using namespace std; int main() {int sum0;for(int i49;i>7;i--)sumi;cout<<sum<<endl;return 0; } 直接暴力&#xff0c;题意很清晰&#xff0c;累加即可。 二、0小球反弹 - 蓝…

跨境卫士跟vps哪个更好用?跨境卫士为卖家提供固定IP环境

跨境卫士是通过为卖家提供固定的环境 i p来隔离本地电脑环境&#xff0c;为卖家创造一个真实独立的物理环境&#xff0c;让买家再任意电脑&#xff0c;任意网络下都能够安全的管理账号。跨境卫士和紫鸟原理一样&#xff0c;是通过为卖家提供固定的环境 i p来隔离本地电脑环境&a…

coding ability 展开第四幕(滑动指针——巩固篇)超详细!!!!

文章目录 前言水果成篮思路 找到字符串中所有字母异位词思路 串联所有单词的子串思路 最小覆盖子串思路 总结 前言 本专栏上一篇博客&#xff0c;带着大家从认识滑动窗口到慢慢熟悉 相信大家对滑动窗口已经有了大概的认识 其实主要就是抓住——一段连续的区间 今天来学习一些滑…

Netty启动源码NioEventLoop剖析accept剖析read剖析write剖析

学习链接 NIO&Netty - 专栏 Netty核心技术十–Netty 核心源码剖析Netty核心技术九–TCP 粘包和拆包及解决方案Netty核心技术七–Google ProtobufNetty核心技术六–Netty核心模块组件Netty核心技术五–Netty高性能架构设计 聊聊Netty那些事儿 - 专栏 一文搞懂Netty发送数…

2024年12月CCF-GESP编程能力等级认证C++编程一级真题解析

一级真题的难度: ‌ CCF-GESP编程能力等级认证C++编程一级真题的难度适中‌。这些真题主要考察的是C++编程的基础知识、基本语法以及简单的算法逻辑。从搜索结果中可以看到,真题内容包括了选择题、编程题等题型,涉及的内容如C++表达式的计算、基本输入输出语句的理解…

73.HarmonyOS NEXT PicturePreviewImage组件深度剖析:高级功能扩展与性能优化策略(三)

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT PicturePreviewImage组件深度剖析&#xff1a;高级功能扩展与性能优化策略(三) 文章目录 HarmonyOS NEXT PicturePreviewImage组件…

六十天前端强化训练之第十七天React Hooks 入门:useState 深度解析

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、知识讲解 1. Hooks 是什么&#xff1f; 2. useState 的作用 3. 基本语法解析 4. 工作原理 5. 参数详解 a) 初始值设置方式 b) 更新函数特性 6. 注意事项 7. 类组…