C++11 14 17线程

news2024/10/3 0:26:03

线程类封装

#include<thread>
#include<iostream>
#include<string>

using namespace std::chrono_literals;
class MyThread {
public:
	void Main() {
		std::cout << "MyThread Main" << name << ":" << age;
	}
private:
	std::string name;
	int age = 100;
};

class XThread {
public:
	virtual void Start() {
		_is_exit = false;
		_th = std::thread(&XThread::Main, this);
	}

	virtual void Stop() {
		_is_exit = true;
		Wait();
	}

	virtual void Wait() {
		if (_th.joinable())
			_th.join();
	}

	bool is_exit() { return _is_exit; }
private:
	virtual void Main() = 0;
	std::thread _th;
	bool _is_exit = false;
};

class TestXThread:public XThread {
public:
	void Main() override {
		while (!is_exit()) {
			std::this_thread::sleep_for(100ms);
			std::cout << "." << std::flush;
		}
	}
	std::string name;
};

超时锁

超时锁是一种同步机制,用于在尝试获取锁时设置一个超时时间。如果线程在指定的时间内无法获取锁,它将放弃,而不是无限期地等待。这种机制对于避免死锁和提高系统的响应性非常有用

try_lock_for(duration): 这个方法允许线程尝试在指定的时间段内获取锁。如果在这段时间内锁未被获取,则返回 false。这里的 duration 是一个表示时间长度的对象,比如可以使用 std::chrono 库来指定

try_lock_for std::timed_mutex 或类似互斥体(如 std::recursive_timed_mutex)的一个成员函数,它尝试在指定时间段内获取锁。如果在这个时间段内成功获得锁,它会返回 true;如果时间段结束时仍未获得锁,它会返回 false。这种机制允许线程不会无限期地等待锁的释放,提高了程序的响应性和灵活性。

递归锁

共享锁

共享锁(Shared Lock),在多线程编程和数据库管理系统中,是一种用于控制对共享资源的并发访问的同步机制。与互斥锁(独占锁)不同,共享锁允许多个线程或进程同时读取同一资源,但在写入时仍然需要独占访问权限。

lock_shared()函数用于获取共享锁,也称为读锁。当你希望多个线程能够同时读取某个共享数据时使用。在任何时刻,可以有多个线程持有共享锁,只要没有线程持有独占锁。这允许多个读操作并行执行,而不会互相冲突,因为读操作通常不会改变数据状态。

lock()函数用于获取独占锁,也称为写锁。当你希望确保只有一个线程能够写入或修改共享数据时使用。独占锁保证了没有其他线程可以同时读取或写入共享资源,确保了对共享资源的独占访问权。

利用RAII

#include <thread>
#include <iostream>
#include <string>
#include <mutex>
#include <shared_mutex>
//Linux -lpthread
using namespace std;
// RAII
class XMutex
{
public:
    XMutex(mutex& mux):mux_(mux)
    {
        cout << "Lock" << endl;
        mux.lock();
    }
    ~XMutex()
    {
        cout << "Unlock" << endl;
        mux_.unlock();
    }
private:
    mutex& mux_;
};
static mutex mux;
void TestMutex(int status)
{
    XMutex lock(mux);
    if (status == 1)
    {
        cout << "=1" << endl;
        return;
    }
    else
    {
        cout << "!=1" << endl;
        return;
    }
}
int main(int argc, char* argv[])
{
    TestMutex(1);
    TestMutex(2);
    
    getchar();
    return 0;
}

lock_guard

std::lock_guard 是 C++ 标准库中的一个模板类,用于简化互斥锁(如 std::mutex)的管理。它实现了一种被称为“范围锁定”(RAII, Resource Acquisition Is Initialization)的模式,确保在持有锁的线程的执行范围内,锁一定会被持有,并在范围结束时自动释放。

#include <thread>
#include <iostream>
#include <string>
#include <mutex>
#include <shared_mutex>
//Linux -lpthread
using namespace std;
// RAII
class XMutex
{
public:
    XMutex(mutex& mux):mux_(mux)
    {
        cout << "Lock" << endl;
        mux.lock();
    }
    ~XMutex()
    {
        cout << "Unlock" << endl;
        mux_.unlock();
    }
private:
    mutex& mux_;
};
static mutex mux;
void TestMutex(int status)
{
    XMutex lock(mux);
    if (status == 1)
    {
        cout << "=1" << endl;
        return;
    }
    else
    {
        cout << "!=1" << endl;
        return;
    }
}

static mutex gmutex;
void TestLockGuard(int i)
{
    gmutex.lock();
    {
        //�Ѿ�ӵ��������lock
        lock_guard<mutex> lock(gmutex,adopt_lock);
        //�����ͷ���
    }
    {
        lock_guard<mutex> lock(gmutex);
        cout << "begin thread " << i << endl;
    }
    for (;;)
    {
        {
            lock_guard<mutex> lock(gmutex);
            cout << "In " << i << endl;
        }
        this_thread::sleep_for(500ms);
    }
}
int main(int argc, char* argv[])
{
    for (int i = 0; i < 3; i++)
    {
        thread th(TestLockGuard, i + 1);
        th.detach();
    }
    TestMutex(1);
    TestMutex(2);

    getchar();
    return 0;
}

unique_lock

在 C++ 中的多线程编程里,锁的标签(或锁策略标签)是一些用于指定锁的行为的标记。这些标签通常与锁管理器(如 std::unique_lockstd::lock_guard)一起使用,来控制互斥量的锁定和解锁行为。以下是一些常见的锁的标签:

  1. std::adopt_lock 这个标签用于指示锁管理器对象,互斥量在传递给锁管理器之前已经被当前线程锁定。锁管理器将“采用”这个已经存在的锁,并在其析构时释放它。使用 std::adopt_lock 需要确保互斥量在传递之前已经被锁定。

  2. std::defer_lock 使用这个标签创建的锁管理器对象不会立即锁定互斥量。这允许延迟锁定操作,直到显式调用锁定方法。这提供了更多的控制,允许在需要时进行锁定。

  3. std::try_to_lock 用这个标签构造的锁管理器会尝试锁定互斥量,但不会阻塞等待。如果互斥量当前不可用(已被其他线程锁定),锁管理器不会持有锁。

shared_lock

scope_lock

std::scoped_lock 是 C++17 标准引入的一个锁管理器,用于简化多个互斥锁的获取和释放,从而帮助避免死锁。它是一种作用域锁(scope-based locking),能够在构造时自动获取一个或多个互斥锁,并在离开作用域(即对象被销毁)时自动释放这些锁。

互斥锁+list模拟线程通信

条件变量

生产者消费者模型

#include <thread>
#include <iostream>
#include <mutex>
#include <list>
#include <string>
#include <sstream>
using namespace std;

list<string> msgs_;
mutex mux;
condition_variable cv;

void ThreadWrite() {
	for (int i = 0;; i++) {
		stringstream ss;
		ss << "Write msg" << i;
		unique_lock<mutex>lock(mux);
		msgs_.push_back(ss.str());
		cv.notify_one();
		this_thread::sleep_for(3s);
	}
}

void ThreadRead(int i) {
	while (true) {
		unique_lock<mutex>lock(mux);
		cout << "read msg" << endl;
		cv.wait(lock, [i] {
			cout << i << "wait" << endl;
			return !msgs_.empty();
			});
	}
	while (!msgs_.empty()) {
		cout << i << "read" << msgs_.front() << endl;
		msgs_.pop_front();
	}
}

int main() {

}

线程的异步和通信

线程池

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

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

相关文章

RFID传感器|识读器CNS-RFID-01/1S在AGV小车|搬运机器人领域的安装与配置方法

AGV 在运行时候需要根据预设地标点来执行指令&#xff0c;在需要 AGV 在路径线上位置执行某个指令时候&#xff0c;则需要在这个点设置 命令地标点&#xff0c;AGV 通过读取不同地标点编号信息&#xff0c;来执行规定的指令。读取地标点设备为寻址传感器&#xff0c;目前&#…

【demoSURF】室内定位(图像匹配)基础代码实现,包含所有可以出现问题的解法

代码如下 import numpy as np import cv2 from matplotlib import pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 用来正常显示中文标签 plt.rcParams[axes.unicode_minus] False # 用来正常显示负号img1 cv2.imread("D:/data/North/0007.JPG",0) i…

你是唯一的 uniq

文章目录 你是唯一的 uniq语法默认无参数统计出现频次仅仅显示重复的行仅仅显示不重复的行更多信息 你是唯一的 uniq Linux uniq 命令用于检查及删除文本文件中重复出现的行列&#xff0c;一般与 sort 命令结合使用。 官方定义为&#xff1a; uniq - report or omit repeated…

第15课 利用openCV实现人脸识别

这节课&#xff0c;我们再来看一个简单且实用的例子&#xff1a;人脸识别。这个小例子可以让你进一步领略openCV的强悍。 1.复制demo14并改名为demo15。 2.修改capImg函数&#xff1a; int fmle::capImg() {// 加载人脸检测分类器cv::CascadeClassifier faceCascade;faceCas…

网络知识-以太网技术的发展及网络设备

目 录 一、背景介绍 &#xff08;一&#xff09;网络技术的时代 &#xff08;二&#xff09;以太网技术脱颖而出 二、以太网的工作原理 &#xff08;一&#xff09;、载波侦听多路访问&#xff08;CSMA/CD&#xff09; 1、数据发送流程 2、发送过程解析 3、…

1.4 Unity协程

一、先说接口 接口是不能实例化的&#xff0c;想实例化接口&#xff0c;只能实例化继承了接口的类。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace InterfaceTest {interface IMyInterfa…

hutool 的 bigExcelWriter.addSelect 失效

原因:可能是下拉列表的数据过多, 解决办法: 添加辅助列 然后只需要往K列加数据就可以了

ssm基于JSP的网络游戏交易系统的设计与实现+jsp论文

摘 要 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;商品管理信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足…

Python基础入门第七课笔记(自定义函数 define)

函数 函数必须先定义再调用 函数必须先定义再调用 函数必须先定义再调用 定义函数&#xff1a; def 函数名&#xff08;形参&#xff09;&#xff1a; 代码1 代码2 ………. 调用函数&#xff1a; 函数名&#xff08;实参&#xff09; 形参&…

浅析观察者模式在Java中的应用

观察者模式&#xff08;Observer Design Pattern&#xff09;,也叫做发布订阅模式&#xff08;Publish-Subscribe Design Pattern&#xff09;、模型-视图&#xff08;Model-View&#xff09;模式、源-监听器&#xff08;Source-Listener&#xff09;模式、从属者&#xff08;D…

吉时利2601A数字源表Keithley 2601A

吉时利2601A源测量单元&#xff08;SMU&#xff09;&#xff0c;也被称为源表&#xff0c;是一种高性能的仪器&#xff0c;能够提供100毫伏至40伏的电压范围&#xff0c;以及100纳至10安的电流范围。这种仪器能够提供的功率高达40.4瓦&#xff0c;使其在台式I-V表征工具或多通道…

VMware中找到存在但是不显示的虚拟机(彻底发现)VMware已创建虚拟机不显示

删除VMware中的虚拟机的时候&#xff0c;可能没有把虚拟机完全删除&#xff0c;或者说 “移除” 后找不到虚拟机在哪里&#xff0c;内存空间也没有得到释放&#xff0c;那该如何解决呢&#xff1f; 1.明确&#xff1a; “移除” 不等于 “从磁盘删除” 移除&#xff1a;只…

篇三:让OAuth2 server支持密码模式

由于Spring-Security-Oauth2停止维护&#xff0c;官方推荐采用 spring-security-oauth2-authorization-server&#xff0c;而后者默认不支持密码授权模式&#xff0c;本篇实战中采用的版本如下&#xff1a; <dependency><groupId>org.springframework.security<…

HarmonOS 通用组件(Button)

本文 我们来看看基础组件中的 Button 这是 ArkTS ui 原生支持的一个组件 用来创建不同样式的按钮 首先 我们还是创建一个最基本的组件结构 Entry Component struct Index {build() {Row() {Column() {}.width(100%)}.height(100%)} }我们可以在 Column 组件中 加入一个button…

Jmeter相关知识介绍

Jmeter 是Apache 组织开发的基于JAVA 的压力测试工具,用于对软件做压力测试,特别适合于WEB 应用测试(包括压力,接口测试) 今天简单介绍Jemeter的入门相关概念的理解 一、在安装目录下有一个Bin\Jmeter.bat 双击打开 打开之后是一个这样的界面 二、测试计划 1、添加和删…

面试十分钟不到就被赶出来了,问的问题有点变态

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到12月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…

【Xilinx FPGA】异步 FIFO 的复位

FIFO&#xff08;First-In-First_Out&#xff0c;先入先出&#xff09;是一种的存储器类型&#xff0c;在 FPGA 开发中通常用于数据缓存、位宽转换或者跨时钟域&#xff08;多 bit 数据流&#xff09;。在使用异步 FIFO 时&#xff0c;应注意复位信号是否遵循相关要求和规范&am…

Mysql show Profiles详解

1.简介 show profile 和 show profiles 命令用于展示SQL语句的资源使用情况&#xff0c;包括CPU的使用&#xff0c;CPU上下文切换&#xff0c;IO等待&#xff0c;内存使用等&#xff0c;这个命令对于分析某个SQL的性能瓶颈非常有帮助&#xff0c;借助于show profile的输出信息&…

啊哈c语言——逻辑挑战9:水仙花数

有一种三位数特别奇怪&#xff0c;这种数的“个位数的立方”加上“十位数的 立方”再加上“百位数的立方”恰好等于这个数。例如&#xff1a; 153111555333&#xff0c;我们为这种特殊的三位数起了一个很好听的名字——“水仙花数”&#xff0c;那么请你找出所有的“水仙花数”…

简易机器学习笔记(四)初识卷积神经网络

前言 第一次写卷积神经网络&#xff0c;也是照着paddlepaddle的官方文档抄&#xff0c;这里简单讲解一下心得。 首先我们要知道之前写的那些东西都是什么&#xff0c;之前写的我们称之为简单神经网络&#xff0c;也就是简单一层连接输出和输出&#xff0c;通过前向计算和逆向…