【Linux】多线程_3

news2024/12/26 23:37:35

文章目录

  • 九、多线程
    • 3. C++11中的多线程
    • 4. 线程的简单封装
  • 未完待续


九、多线程

3. C++11中的多线程

Linux中是根据多线程库来实现多线程的,C++11也有自己的多线程,那它的多线程又是怎样的?我们来使用一些C++11的多线程。
Makefile

testThread: testThread.cc
	g++ -o $@ $^ -std=c++11
.PHONY: clean
clean:
	rm -f testThread

testThread.cc

#include <iostream>
#include <thread>
#include <unistd.h>
using namespace std;

void threadrun(int num)
{
    while (num)
    {
        cout << "I am thread, num : " << num << endl;
        sleep(1);
        --num;
    }
}

int main()
{
    thread t1(threadrun, 10);
    while (true)
    {
        cout << "I am main thread" << endl;
        sleep(1);
    }

    t1.join();
    
    return 0;
}

编译看看:
在这里插入图片描述
我们发现有问题(也可能是其他问题),这是怎么回事呢?其实是 C++11的多线程本质上是对原生线程的封装。所以同样需要链接 phread 动态库。
Makefile

testThread: testThread.cc
	g++ -o $@ $^ -std=c++11 -lpthread
.PHONY: clean
clean:
	rm -f testThread

我们再试试:
在这里插入图片描述
确实大部分其编程语言的多线程都是对原生线程的封装,原因是为了可移植性。
我们在进程部分学过 非阻塞等待 ,进程在等待子进程退出时,可以执行其他任务,在线程这里,同样有这样的技术,叫做线程分离。我们要是不关注线程的结果,只需要线程把自己的任务完成,这种情况就可以将线程进行分离。
在这里插入图片描述
Makefile

testThread: testThread.cc
	g++ -o $@ $^ -std=c++11 -lpthread
.PHONY: clean
clean:
	rm -f testThread

testThread.cc

#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>
using namespace std;

void* threadrun(void* args)
{
    string str = (const char*)args;
    int cnt = 5;
    while (true)
    {
        if (!(cnt--)) break;
        cout << "I am a new thread " << endl;
        sleep(1);
    }
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, threadrun, (void*)"thread1");
    // 线程分离
    pthread_detach(tid);

    while (true)
    {
        cout << "I am the main thread " << endl;
        sleep(1);
    }

    return 0;
}

在这里插入图片描述

默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏。
如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。

joinable和分离是冲突的,一个线程不能既是joinable又是分离的。如果将线程分离了又对其join,就会出错。
线程分离底层依旧是属于进程,没有分开,线程分离只是一种状态,唯一的区别就是主线程不需要等待新线程。

4. 线程的简单封装

Makefile

testThread: testThread.cc
	g++ -o $@ $^ -std=c++11 -lpthread
.PHONY: clean
clean:
	rm -f testThread

Thread.hpp

#ifndef __THREAD_HPP__
#define __THREAD_HPP__

#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>
#include <unistd.h>

// 线程命名空间
namespace ThreadModule
{
    // 线程函数模板
    template<typename T>
    using func_t = std::function<void(T&)>;

    // 线程模板
    template<typename T>
    class Thread
    {
    public:
        Thread(func_t<T> func, T data, const std::string& name = "none-name")
        :_func(func)
        ,_data(data)
        ,_threadname(name)
        ,_stop(true)
        {}

        void Excute()
        {
            _func(_data);
        }

        static void* threadtoutine(void* args)
        {
            Thread<T>* self = (Thread<T>*)args;
            self->Excute();
            return nullptr;
        }

        // 启动线程
        bool Start()
        {
            int n = pthread_create(&_tid, nullptr, threadtoutine, this);
            if (n == 0)
            {
                _stop = false;
                return true;
            }
            else return false;
        }

        // 分离线程
        void Detach()
        {
            if (!_stop)
            {
                pthread_detach(_tid);
            }
        }

        // 等待线程结束
        void Join()
        {
            if (!_stop)
            {
                pthread_join(_tid, nullptr);
            }
        }

        std::string name()
        {
            return _threadname;
        }

        // 停止线程
        void Stop()
        {
            _stop = true;
        }

        ~Thread(){}
    private:
        pthread_t _tid;
        std::string _threadname;
        T _data;
        func_t<T> _func;
        bool _stop;
    };
}

#endif

testThread.cc

#include <iostream>
#include <vector>
#include "Thread.hpp"
using namespace ThreadModule;

const int num = 10;

// 线程执行的任务
void print(int& cnt)
{
    while (cnt)
    {
        std::cout << "hello I am myself thread, cnt: " << cnt-- << std::endl;
        sleep(1);
    }
}

int main()
{
    // 创建多线程
    std::vector<Thread<int>> threads;
    // 创建num个线程,每个线程执行print函数
    for (int i = 0; i < num; ++i)
    {
        std::string name = "thread-" + std::to_string(i + 1);
        threads.emplace_back(print, 10, name);
    }

    // 启动线程
    for (auto& thread : threads)
    {
        thread.Start();
    }

    // 等待线程结束
    for (auto& thread : threads)
    {
        thread.Join();
        std::cout << "wait thread done, thread name: " << thread.name() << std::endl;
    }

    return 0;
}

结果:
在这里插入图片描述


未完待续

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

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

相关文章

防火墙组网与安全策略实验

实验要求&#xff1a; 实现&#xff1a; 防火墙接口配置&#xff1a; 所有接口均配置为三层接口 由于G1/0/3口下为vlan环境&#xff0c;所以防火墙需要配置子接口 &#xff1a; 交换机划分vlan分开生产区和办公区、配置trunk干道 &#xff1a; 安全策略&#xff1a; 生产区访…

【中项第三版】系统集成项目管理工程师 | 第 4 章 信息系统架构④ | 4.7

前言 第4章对应的内容选择题和案例分析都会进行考查&#xff0c;这一章节属于技术相关的内容&#xff0c;学习要以教材为准。本章分值预计在4-5分。 目录 4.7 安全架构 4.7.1 安全威胁 4.7.2 定义与范围 4.7.3 整体架构设计 4.7.4 网络安全架构设计 4.7.5 数据库系统安…

Pod资源-持久化-网络暴露-env

一.资源清单 资源清单组成 apiVersion&#xff1a;v1 #对应不同的k8s版本中的api&#xff1b; kind&#xff1a;Pod #资源的名称&#xff08;service、ConfigMap、hpa.....&#xff09; metadata&#xff1a; #声明资源的元数据信息&#xff08;资源的…

JavaWeb后端学习

Web&#xff1a;全球局域网&#xff0c;万维网&#xff0c;能通过浏览器访问的网站 Maven Apache旗下的一个开源项目&#xff0c;是一款用于管理和构建Java项目的工具 作用&#xff1a; 依赖管理&#xff1a;方便快捷的管理项目以来的资源&#xff08;jar包&#xff09;&am…

Linux - 探索命令行

探索命令行 Linux命令行中的命令使用格式都是相同的: 命令名称 参数1 参数2 参数3 ...参数之间用任意数量的空白字符分开. 关于命令行, 可以先阅读一些基本常识. 然后我们介绍最常用的一些命令: ls用于列出当前目录(即"文件夹")下的所有文件(或目录). 目录会用蓝色…

初学编程不知道怎么选?推荐学习的三种热门编程语言

在当今的社会需求下&#xff0c;市场上最常见、最受欢迎、最广泛应用的编程语言主要有三种&#xff1a;C语言、Java语言和Python语言。 既然要做出选择&#xff0c;我们就需要明白这三种编程语言各自有何特点和区别。 一、特点 C语言 高效与灵活&#xff1a;C语言生成的机器…

Date/SimpleDateFormat

Date 在Java中&#xff0c;java.util.Date 类用于表示日期和时间。它以自1970年1月1日00:00:00 GMT 一来的毫秒数来存储日期和时间信息。 1、构造方法 标准基准时间&#xff08;称为“历元&#xff08;epoch&#xff09;”&#xff1a;即1970年1月1日00:00:00 GMT。 tips: …

4G LTE教程

整体架构 物理层&#xff08;第 1 层&#xff09; 物理层通过空中接口传输来自 MAC 传输信道的所有信息。负责 RRC 层的链路自适应 (AMC)、功率控制、小区搜索&#xff08;用于初始同步和切换目的&#xff09;和其他测量&#xff08;LTE 系统内部和系统之间&#xff09;。 介…

运行在Linux上的程序越来越慢的排查思路

1、通过free -h 排查内存使用情况&#xff0c;是否内存满了 2、通过df -h 排查磁盘的使用情况&#xff0c;磁盘是否没有空间了 3、检查系统资源配置情况&#xff0c;比如使用ulimit -a检查当前会话的资源限制&#xff0c;如最大文件数、打开文件描述符数等&#xff0c;看是否…

vue 前端项目调用后端接口记录

axios中不同的类型的请求附带数据使用的关键字 请求类型关键字示例GETparamsaxios({ method: get, url: example.com, params: { key: value } })POSTdataaxios({ method: post, url: example.com, data: { key: value } })PUTdataaxios({ method: put, url: example.com, dat…

快速读出linux 内核中全局变量

查问题时发现全局变量能读出来会提高效率&#xff0c;于是考虑从怎么读出内核态的全局变量&#xff0c;脚本如下 f open("/proc/kcore", rb) f.seek(4) # skip magic assert f.read(1) b\x02 # 64 位def read_number(bytes):return int.from_bytes(bytes, little,…

深度解读李彦宏的“不要卷模型,要卷应用”

深度解读李彦宏的“不要卷模型&#xff0c;要卷应用” —— AI技术的应用之道 引言 在2024世界人工智能大会的舞台上&#xff0c;李彦宏的“不要卷模型&#xff0c;要卷应用”言论犹如一石激起千层浪&#xff0c;引发了业界对AI技术发展路径的深思。本文将深入探讨这一观点&a…

修改vscode的字体为等宽字符

在文件——首选项——设置 中 搜索 Editor: Font Family 将内容改为下面的 Consolas, Courier New, monospace 之后重启Vscode就行了

vs2017/2019串口Qt Serial Port/modbus使用报错

vs2017/2019 Qt Serial Port/modbus配置 /* * 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 LNK2019 无法解析的外部符号 "__declspec(dllimport) public: __cdecl QModbusTcpClient::QModbusTcpClient(class QObject *)" (__imp_??…

【代码随想录】【算法训练营】【第66天】 [卡码95]城市间货物运输II [卡码96]城市间货物运输III

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 卡码网。 day 66&#xff0c;周五&#xff0c;ding ding~ [卡码95] 城市间货物运输II 题目描述 卡码95 城市间货物运输II 解题思路 前提&#xff1a; 思路&#xff1a; 重点&#xff1a; 代码实现 C语言 …

智慧养殖的智慧网络:构建高效、可扩展的养殖生态

智慧养殖&#xff0c;在国家政策的大力扶持和农业数字化浪潮的推动下&#xff0c;正迅速发展。然而&#xff0c;许多人对它的价值仍持怀疑态度&#xff1a;认为智慧养殖只是昂贵的技术堆砌&#xff0c;短期内看不到经济回报&#xff0c;甚至怀疑其实用性。本文将挑战这些观点&a…

百川工作手机监控企业员工微信行为

在数字化转型的浪潮中&#xff0c;企业沟通方式正经历着前所未有的变革。微信&#xff0c;作为日常交流不可或缺的工具&#xff0c;已成为企业内外协作的重要桥梁。然而&#xff0c;随着业务量的激增&#xff0c;如何有效监控与管理员工在微信上的行为&#xff0c;确保信息安全…

LLM推理优化笔记1:KV cache、Grouped-query attention等

KV cache 对于decoder-only 模型比如现在如火如荼的大模型&#xff0c;其在生成内容的过程中&#xff0c;为了避免冗余计算&#xff0c;会将Transformer里的self-attention的K和V矩阵给缓存起来&#xff0c;这个过程即为KV cache。 decoder-only模型的生成过程是自回归的&…

让人工智能为你的旋律填词,开启音乐新章

在音乐的世界里&#xff0c;旋律如同灵动的精灵&#xff0c;飞舞在我们的心间。但有时&#xff0c;为这美妙的旋律找到最贴切、最动人的歌词&#xff0c;却成为了创作者们的难题。如今&#xff0c;随着科技的进步&#xff0c;人工智能正逐渐成为我们在音乐创作道路上的得力助手…

【香橙派 Orange pi AIpro】| 开发板深入使用体验

目录 一. &#x1f981; 写在前面二. &#x1f981; 愉快的安装流程2.1 安装前准备2.2 流程准备2.2.1 烧录镜像2.2.2 开机2.2.3 连网2.2.4 SSH远程连接开发板 2.3 体验 AI 应用样例 三. &#x1f981; 写在最后 一. &#x1f981; 写在前面 大家好&#xff0c;我是狮子呀&…