从 C++ 单例 pthread_once 到 double-check、volatile、memory barrier

[并发并行]_[线程同步]_[pthread_once 实现单例模式分析] http://blog.youkuaiyun.com/infoworld/article/details/49798215 mingw 编译,Win32部分可以直接用vs编译. 立即下载

pthread_once 确保一个被注册的子函数至多被执行一次:

#include <pthread.h>
#include <cassert>

using namespace std;

class Singleton
{
public:
  static
    Singleton *instance();
private:
  static
    Singleton *instance_;
  static
    pthread_once_t once;
  static
    void _instance();
  Singleton();
};

Singleton::Singleton()
{
};

Singleton *Singleton::instance_ = NULL;

void Singleton::_instance()
{
  assert(NULL == instance_);
  instance_ = new Singleton();
}

pthread_once_t Singleton::once = PTHREAD_ONCE_INIT;

Singleton *Singleton::instance()
{
  pthread_once(&once, Singleton::_instance);
  return instance_;
}


下面这段代码,看起来非常和谐的 double-check,what problem?

pthread_mutex_t singleton_mutex = PTHREAD_MUTEX_INITIALIZER;

Singleton *Singleton::instance2()
{
  if (NULL == instance_) {
    pthread_mutex_lock(&singleton_mutex);
    if (NULL == instance_) {
      instance_ = new Singleton();
    }
    pthread_mutex_unlock(&singleton_mutex);
  }
  return instance_;
}

悲剧在于,由于实现机制的原因,可能存在这一种情况,instance_ 指针先被赋值,而后执行 initializer,在这个初始化完成之前,对于另一个线程而言,这个指针看起来指向一个被初始化过的对象,错误地使用了这个变量!


参考这篇文章: 原子,锁,还有内存屏障 主要讨论指令乱序导致的问题;而这篇:Linux 内核中的内存屏障 讨论的是 cache line 导致的问题。


TO BE CONTINUED......

Vscode远程免密连接Linux虚拟机,并配置C/C++运行环境 目前想要深入学习在Linux,也为了方便编写C/C++程序。Linux的环境里一般自带有c++的编译环境,如果没有安装gcc和g++等编译器也比较便利。但是在虚拟机里用vim编写C++程序又不得劲,因此打算使用vscode远程连接Linux虚拟机进行学习。为了防止自己以后还要再配置,重复踩坑,因此写下这篇博客用做记录。环境:windows11、VMware17、rocky linux9.1 ( 开源的CentOS9 ) 阅读详情

相关推荐

深入浅出ISP:用RKISP2.x Tuner工具理解AWB、AE、HDR等核心模块的实战调参

本文深入解析RKISP2.x Tuner工具在ISP图像处理中的实战应用,重点探讨AWB、AE、HDR等核心模块的调参技巧。通过环境搭建、调试工具使用和实际案例,帮助开发者掌握如何在不同光照条件下优化图像质量,实现精准的白平衡、曝光控制和动态范围处理。

weixin_26802933的博客 487

C/C++编程:pthread_once

函数声明 int pthread_once(pthread_once_t *once_control, void (*init_routine) (void)); 本函数使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进程执行序列中仅执行一次。 使用示例 #include <semaphore.h> #include <sys/types.h> #include <dirent.h> #include &

OceanStar的博客 573

WSL Ubuntu20 通过1Panel配置SSH服务的完整避坑指南

本文详细介绍了在WSL Ubuntu20环境下通过1Panel配置SSH服务的完整指南,包括环境准备、SSH服务安装与基础配置、1Panel中的SSH管理技巧以及连接测试与故障排查。特别针对WSL特性提供了避坑建议,如IP动态变化处理、SSH服务初始化配置等关键步骤,帮助用户高效搭建稳定的SSH服务环境。

weixin_29239279的博客 414

pthread_once单例模式

在陈硕的《Linux多线程服务端编程》上的使用pthread_once实现的单例模式 template class Singleton : boost::noncopyable { public:     static T& instance(){         pthread_once(&once_, &Singleton::init);         return *valu

tom555cat 4198

打开LWIP_DEBUG的打印信息调试

在lwip 2.1.2的版本,打开的debug 调试的步骤: 1.在debug.h 文件中找到debug打印的定义 默认LWIP_DEBUG这个宏没有定义, 2.在lwipopt.h 文件中或者其他文件定义 一下LWIP_DEBUG这个宏, 3.在opt.h 中可以打开各种宏的调试信息, /* --------------------------------------- ---------- Debugging options ---------- ---------...

haidscs的博客 9880

离线安装PlutoSDR硬件支持包全攻略:没有MathWorks账号也能搞定MATLAB集成

本文详细介绍了在没有MathWorks账号和网络环境的情况下,如何离线安装PlutoSDR硬件支持包并实现MATLAB集成的完整解决方案。从驱动安装、设备识别到MATLAB支持包的离线部署,提供了全面的步骤指导和常见问题排查方法,特别适合高校实验室、军工单位等内网环境使用。

js777的博客 267

C++使用pthread_once实现单例模式模板类

C++单例模式: //singleton.h template<typename T> class Singleton : noncopyable { public: static T& Instance() { pthread_once(&ponce_, &Singleton::init); return *...

xu215740578的博客 802

路径跟踪 | 图解路径跟踪PID算法(附ROS C++/Python/Matlab仿真)

PID控制是一种经典的控制算法,广泛应用于各种工业场景。在基于PID的局部路径规划中,希望机器人能快速跟踪上预设的轨迹。本文介绍PID控制的基本原理,并基于PID控制律设计路径跟踪算法,最后通过ROS C++/Python/Matlab进行仿真实现,加深理解

FRIGIDWINTER的博客 1万+

C语言之pthread_once实例总结(八十三)

本篇目的:理解pthread_once函数用法函数是POSIX线程库中的一个函数,用于在单线程环境中进行线程安全的初始化。该函数确保仅在第一次调用时执行给定的初始化代码,而不会重复执行。这对于需要在程序启动时进行初始化,但只执行一次的操作非常有用。函数保证函数在多线程环境下只被调用一次。是一个用来控制函数是否被调用的控制变量。是需要保证只调用一次的函数。如果函数成功执行,返回0。如果函数失败,返回一个非零值。使用。

Android系统攻城狮 1202

【Davinci开发】:CS接口创建及连接

AUTOSAR SWC之间添加CS-port :详细讲解step

2527

使用自制的NTC测量模块测试Plecs的热仿真效果

可以测试:您完全可以用这个模型来测试热仿真。NTC 模型是连接电气域和热域的关键桥梁。实现闭环:通过这种方式,您创建了一个高度真实的正反馈闭环系统:负载增加 -> 损耗增加 -> 温度升高 -> NTC 阻值变化 -> 控制电路可能因此调整(如降低频率或电流)-> 损耗变化 -> 温度变化。应用场景:这对于设计过温保护 (OTP) 电路风扇控制系统以及分析热失控条件非常有用。单位:确保热域中使用的单位( Kelvin 或 Celsius )与您的 C-Script 模型输入期望的单位一致。

311

线程安全的单例模式 -- 使用pthread_once一次初始化

一次初始化用到的API:pthread_once_t once_control = PTHREAD_ONCE_INIT;int pthread_once(pthread_once_t* once_control, void (*init_routine)(void));有些事需要一次且仅需要一次执行。通常当初始化应用程序时,可以比较容易地将其放在main函数中。但当你写一个库时,就不能在main里面

未来之歌 2282

AI智能体丨使用Coze一键生成爆款书单视频,3个月内获赞131.1w!(附保姆级教程)

这篇教程详细介绍了如何使用扣子(Coze)平台的AI智能工作流批量制作爆款书单视频。通过自动化流程,只需1-2分钟即可生成45-50秒的书单视频,效率提升近百倍。工作流包含文案生成、音频合成、图片素材获取、视频剪辑等全流程,支持随机生成8本书单、自动提取金句、智能配音等功能。教程提供了完整的操作步骤,包括剪映草稿配置、特效添加等细节,并附体验链接和示例效果。最终生成的视频包含书单展示、金句字幕、背景音乐等元素,适合书单号运营者快速批量产出内容。

李同学Lino的博客 2354

c++多线程多进程服务器muduo相关函数查询表(二)

如表一所示,本文也只是作为记录,想了解具体的函数使用方法,请进入相应的链接中查看: 1、pthread_once(pthread_once_t *once_control, void (*init_routine) (void)) 在多线程环境中,有些函数仅需要执行一次,可以采用pthread_once来声明,具体是哪个线程 执行由Linux内核调度来进行 https://blog.cs...

weixin_38428439的博客 288

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

C++单例的安全实现,double-check(双重检查锁定)的安全实现方法

本文使用C++11 实现饿汉式和懒汉式单例,包括double-check

Where there is life, there is hope. 4757

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C++11 修复了双重检查锁定问题(转)

从网上看到了一篇这个文章,收藏一下   导读:本文是关于C++11标准中修复了双重检查锁定模式的消息,同时作者阐述了实现双重检查锁定模式的诸多方法,并逐一进行了分析,作者还提供了一个在早期编译器上实现双重检查锁定模式的库。 双重检查锁定模式(DCLP)在无锁编程(lock-free programming)中经常被讨论,直到2004年,JAVA才提供了可靠的双重检查锁定实现。而在C++11...

简约不简单 500

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++ double check

学习Double-Checked Locking is Fixed In C++11 (preshing.com) double check在多线程编程中经常见到,但是double check 还不够。 拿单例模式举例 // 普通单例 Singleton* Singleton::getInstance() { if (m_instance == nullptr) { m_instance = new Singleton; } return m_instance...

LiftHandofGod的博客 640

pthread_once()函数详解

线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者。传统的Unix也支持线程的概念,但是在一个进程(process)中只允许有一个线程,这样多线程就意味着多进程。 现在,多线程技术已经被许多操作系统所支持,包括Windows/NT,当然,也包括Linux。 为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些

tianmo2010的专栏 2011

pthread_once()使用(某个时间在整个程序中仅执行一次,不确定是那个线程)

在多线程环境中,有些事仅需要执行一次。通常当初始化应用程序时,可以比较容易地将其放在main函数中。但当你写一个库时,就不能在main里面初始化了,你可以用静态初始化,但使用一次初始化(pthread_once)会比较容易些。 int pthread_once(pthread_once_t *once_control, void (*init_routine) (void)); 功能:本函

轻飘飞扬 1万+

__pthread_once 源码解析

想到这个主题,也是由于最近在写自己的开源代码时,发现使用的singleton类是线程不安全的,虽然在应用主线程都已确保了初始化的正确性,但从一个通用库的角度来讲,这么做就无法保证使用者不出问题,也限制了自由度,pthread_once就是解决这个问题的一个良方,不过首先我们还是先从一些基本的singleton实现说起。 网上关于singleton类的实现真是一搜一箩筐,从最简单的说起(注:为

abcd1f2的专栏 1497

Linux多线程学习(六)pthread_once

int pthread_once(pthread_once_t *once_control,void(*init_routine)(void)); 参数: once_control         控制变量 init_routine         初始化函数 返回值: 若成功返回0,若失败返回错误编号。  类型为pthread_once_t的变量是一个

笑也有泪的专栏 4742

pthread_once 函数

文章出处:http://hi.baidu.com/_%C2%B7_%C8%CB_%BC%D7_/blog/item/4deb8f2b1707bf221f3089a6.html   仅执行一次的操作 int pthread_once(pthread_once_t *onc

韦编二绝 3500

【设计模式C++】单例模式

静态变量的内存分配和初始化 全局变量、non-local static变量(文件域的静态变量和类的静态成员变量)在main执行之前的静态初始化过程中分配内存并初始化;local static 变量(局部静态变量)则是在第一次使用时分配内存并初始化。这里的变量包含内置数据类型和自定义类型的对象。 静态变量初始化的线程安全性说明 非局部静态变量一般在main执行之前的静态初始化过

mick_seu的博客 5366

Linux下pthread_once()函数

函数声明 int pthread_once(pthread_once_t *once_control, void (*init_routine) (void)); 本函数使用初值为PTHREAD_ONCE_INIT的once_control变量保证init_routine()函数在本进程执行序列中仅执行一次。 例子 #include &lt;semaphore.h&gt; #inc...

老王的技术博客 1万+

c++ linux pthread函数

一、pthread1.int pthread_create (pthread_t *pThread, const pthread_attr_t *pAttr, void * (*start_routine)(void *),void *arg);函数说明:创建一个线程;参数说明:参数一:线程id,创建线程时,为每一个线程分配一个Id。 参数二:线程属性,后面详细介绍线程属性。 参数三:线程函数,注...

一技旁身 6323
上一篇: Linux 查单词
下一篇: Ubuntu 14.04 Matlab 2012a plot / title / xlabel / ylabel 无法修改字体及大小
吴-俊宇
博客等级 码龄12年 0粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值