添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
帅呆的韭菜  ·  5、Java ...·  1 年前    · 
豪情万千的芹菜  ·  object is not ...·  1 年前    · 

static变量初始化顺序

1.1 全局变量、文件域的static变量和类的static成员变量在main函数执行之前初始化
1.2 局部静态变量在第一次被使用时初始化

static变量的线程安全

2.1 非局部静态变量是线程安全的
2.2 局部静态变量在C++11后也是线程安全的

分为懒汉式和饿汉式,在使用前全局对象已经创建的是饿汉式单例,在使用的时候创建的是懒汉式单例

01. 普通懒汉式单例,线程不安全

// 懒汉式单例模式,线程不安全
class SingleInstance {
 public:
   static SingleInstance *GetInstance() {
     if (m_SingleInstance == nullptr)
       m_SingleInstance = new SingleInstance;
     return m_SingleInstance;
 private:
   SingleInstance();
   ~SingleInstance();
   SingleInstance(const SingleInstance &signal) = delete;
   SingleInstance &operator=(const SingleInstance &signal) = delete;
 private:
    static SingleInstance *m_SingleInstance;
SingleInstance *SingleInstance::m_SingleInstance = NULL;

02. 加锁的懒汉式单例,线程安全

//懒汉式单例,加锁,线程安全
class SingleInstance {
 public:
   static SingleInstance *GetInstance() {
     pthread_mutex_lock(&mutex);
     if (m_SingleInstance == nullptr)
       m_SingleInstance = new SingleInstance;
     return m_SingleInstance;
     pthread_mutex_unlock(&mutex);
 private:
   SingleInstance();
   ~SingleInstance();
   SingleInstance(const SingleInstance &signal) = delete;
   SingleInstance &operator=(const SingleInstance &signal) = delete;
   static SingleInstance *m_SingleInstance;
   static pthread_mutex_t mutex;
SingleInstance *SingleInstance::m_SingleInstance = NULL;

03. 局部静态变量实现的懒汉式单例,C++11后线程安全(推荐使用的方式)

// 局部静态变量实现的懒汉式单例,C++11后线程安全
class SingleInstance {
 public:
   static SingleInstance *GetInstance() {
     static SingleInstance instance;
     return &instance;
 private:
   SingleInstance();
   ~SingleInstance();
   SingleInstance(const SingleInstance &signal) = delete;
   SingleInstance &operator=(const SingleInstance &signal) = delete;

04. 饿汉式单例,天生线程安全,因为在main函数前已经初始化

//饿汉式单例,天生线程安全
class SingleInstance {
public:
  static SingleInstance *GetInstance() { return m_SingleInstance; }
private:
  SingleInstance();
  ~SingleInstance();
  SingleInstance(const SingleInstance &signal) = delete;
  SingleInstance &operator=(const SingleInstance &signal) = delete;
private:
  static SingleInstance *m_SingleInstance;
SingleInstance *SingleInstance::m_SingleInstance = new SingleInstance;
static变量初始化顺序1.1 全局变量、文件域的static变量和类的static成员变量在main函数执行之前初始化1.2 局部静态变量在第一次被使用时初始化static变量的线程安全2.1 非局部静态变量是线程安全的2.2 局部静态变量在C++11后也是线程安全的单例模式分为懒汉式和饿汉式,在使用前全局对象已经创建的是饿汉式单例,在使用的时候创建的是懒汉式单例01. 普通懒汉式单例,线程不安全// 懒汉式单例模式,线程不安全class SingleInstance static 是一种修饰符,它被用来控制变量的存储方式和可见性。 2、什么时候用static? (1).需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。 (2).有些时候,我们希望我们所引用的类,只存在一个对象,这时候,我们就可以通过static来实现一个单例类。这种模式也叫单例模式。 被static修饰...
线程安全单例模式 一、懒汉模式:即第一次调用该类实例的时候才产生一个新的该类实例,并在以后仅返回此实例。 需要用锁,来保证其线程安全性:原因:多个线程可能进入判断是否已经存在实例的if语句,从而non thread safety。 使用double-check来保证thread safety。但是如果处理大量数据时,该锁才成为严重的性能瓶颈。 1、静态成员实例的懒汉模式: class Singleton private: static Singleton* m_instance; Singleton(){} public: static Singleton* getInst
静态变量static)的线程安全 C++11 Singleton. Static variable is thread safe? Why? stack overflow 在单例模式中我们常常会遇到如下的方法,但是假如同时有多个线程调用了这个函数,它能保证线程安全吗? Singleton& Singleton::GetInstance() static Singleton i...
std::cout << “construct start” << std::endl; std::this_thread::sleep_for(std::chrono::seconds(5)); //构造函数中休眠5s num++; std::cout &lt
C++实现一个线程安全的单例工厂实现代码 我们见到经常有人用 static 局部对象的方式实现了类似单例模式,最近发现一篇文章明确写明 编译器在处理  static局部变量的时候 并不是线程安全的 !!! http://blogs.msdn.com/b/oldnewthing/archive/2004/03/08/85901.aspx     于是实现了一个单例工厂  并且是线程安全的 #ifndef SINGLETONFACTORY_H #define SINGLETONFACTORY_H #include windows.h #include <memory> namespace
  前段时间在网上看到了个的面试题,大概意思是如何在不使用锁和C++11的情况下,用C++实现线程安全的Singleton。   看到这个题目后,第一个想法是用Scott Meyer在《Effective C++》中提到的,在static成员函数中构造local static变量的方法来实现,但是经过一番查找、思考,才明白这种实现在某些情况下是有问题的。本文主要将从基本的单线程中的Singleton开始,慢慢讲述多线程与Singleton的那些事。   在单线程下,下面这个是常见的写法: template<typename> class Singleton
1. 创建一个基于对话框的应用程序。并增加如图所示控件;分别为3个进度条控件关联三个进度条类型的变量;并在对话框的初始化函数中,设定进度条的范围;为编辑框关联一个整型的变量;为12个按钮添加消息处理函数; 2. 定义结构体:用做线程函数的参数传递 typedef struct Threadinfo{ CProgressCtrl *progress;//进度条对象 int speed; //进度条速度 int pos; //进度条位置 } thread,*lpthread; 3. 为对话框增加三个句柄,用于标识各个线程; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 在增加三个结构体类型的变量,用做线程函数的参数传递; HANDLE hThread1; //线程1线程句柄 HANDLE hThread2; //线程2线程句柄 HANDLE hThread3; //线程3线程句柄 4. 新增一个静态的全局变量,用于记录所有线程的状态:static int GlobalVar=10000; 5. 声明并编写线程函数,注意只能有一个参数,且函数的返回值类型也是固定的;函数名可以自定义; DWORD WINAPI ThreadFun(LPVOID pthread);//线程入口函数 6. 在启动按钮的消息处理函数中编写如下代码: thread1.progress=&m_progress1;//进度条对象 thread1.speed=100;//速度 thread1.pos=0;//初始位置 hThread1=CreateThread(NULL,0,ThreadFun,&thread1;,0,0);//创建并开始线程 if (!hThread1) MessageBox("创建线程失败"); 7. 编写线程函数(一般是一个死循环,或者需要花费时间很长的算法!否者就失去了多线程的意义) DWORD WINAPI ThreadFun(LPVOID pthread) //线程入口函数 lpthread temp=(lpthread)pthread;//参数强制转换为结构体类型 temp->progress->SetPos(temp->pos); //设置被传递过来的进度条的位置 while(temp->posspeed); /设置速度 temp->pos++; //增加进度 temp->progress->SetPos(temp->pos); //设置进度条的新位置 GlobalVar--; if(temp->pos==20) temp->pos=0; //进度条满则归0 return true; 8. 在挂起按钮函数中,编写如下代码: if(SuspendThread(hThread1)==0xFFFFFFFF) MessageBox("挂起失败!进程可能已经死亡或未创建!"); return; 9. 在执行按钮函数中,编写如下代码: if(ResumeThread(hThread1)==0xFFFFFFFF) MessageBox("执行失败!进程可能已经死亡或未创建!"); return; 10. 在停止按钮函数中,编写如下代码: if(TerminateThread(hThread1,0))//前些终止线程 CloseHandle(hThread1);//销毁线程句柄 MessageBox("终止进程失败!"); 11. 为应用程序添加WM_TIMER消息,实时更新全局变量的值到编辑框;
关于内存分配:由于static对象都是存储在全局数据段(对应可执行文件中的数据段),这些对象的内存都是在编译时就已经分配好了。 关于初始化: C与C++表现得不同:由于C没有构造函数,因此初始化其实在编译时候已经完成; 而C++含有构造函数,需要调用对应的二进制代码,因此不可能在编译的时候完成。 对于全局对象、全局static对象、类static成员这些都是在main函数执行前调用构造函数进行初始...
阅读之前可以先回顾一下static的主要使用情况: 1、static方法 static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。 但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可