首页 > 其他分享 ><二>强弱指针使用场景之 多线程访问共享对象问题

<二>强弱指针使用场景之 多线程访问共享对象问题

时间:2022-12-02 16:44:16浏览次数:41  
标签:std weak pa 访问共享 shared 多线程 ptr 指针

代码1

#include <iostream>
#include <thread>
using namespace std;


class A {

public:
	A()  { cout  << "A()"  << endl; }
	~A() { cout  << "~A()" << endl; }
	void funcA() {
		cout << "A function()" << endl;
	}
};

void  thread_Handler(A  *pa) {

	std::this_thread::sleep_for(std::chrono::seconds(2));
	pa->funcA();

}

int main() {

	A *pa = new A();

	thread t1(thread_Handler, pa);

	delete pa;

	t1.join();

	return 0;
}

上面代码的问题:
std::this_thread::sleep_for(std::chrono::seconds(2));
后 pa指针已经main 线程中delete 掉了,删掉之后在访问 funcA()函数是不合理的
应该修改为

void  thread_Handler(A  *pa) {

	std::this_thread::sleep_for(std::chrono::seconds(2));
        if(pa所指向的对象是否还有效)
        {
           pa->funcA();
        }
}

//针对上面的场景,我们可以使用强弱智能指针,修改如下

代码2

#include <iostream>
#include <thread>
using namespace std;

class A {

public:
	A()  { cout  << "A()"  << endl; }
	~A() { cout  << "~A()" << endl; }
	void funcA() {
		cout << "A function()" << endl;
	}
};

void  thread_Handler(weak_ptr<A>  pa) {

	std::this_thread::sleep_for(std::chrono::seconds(2));
	shared_ptr<A> ptr = pa.lock();
	if (ptr == nullptr) {
		cout << "对象已经销毁了" << endl;
	}
	else {
		ptr->funcA();
	}
}

int main() {

	{
		shared_ptr<A> ptr(new A());

		thread t1(thread_Handler, weak_ptr<A>(ptr));
	
		t1.detach();
	}

	std::this_thread::sleep_for(std::chrono::seconds(10));
	return 0;
}

share_ptr
share_ptr是C++11新添加的智能指针,它限定的资源可以被多个指针共享。

只有指向动态分配的对象的指针才能交给 shared_ptr 对象托管。将指向普通局部变量、全局变量的指针交给 shared_ptr 托管,编译时不会有问题,但程序运行时会出错,因为不能析构一个并没有指向动态分配的内存空间的指针

weak_ptr
weak_ptr是一种用于解决shared_ptr相互引用时产生死锁问题的智能指针。如果有两个shared_ptr相互引用,那么这两个shared_ptr指针的引用计数永远不会下降为0,资源永远不会释放。weak_ptr是对对象的一种弱引用,它不会增加对象的use_count,weak_ptr和shared_ptr可以相互转化,shared_ptr可以直接赋值给weak_ptr,weak_ptr也可以通过调用lock函数来获得shared_ptr。

weak_ptr指针通常不单独使用,只能和 shared_ptr 类型指针搭配使用。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。即使有weak_ptr指向对象,对象也还是会被释放。
weak_ptr并没有重载operator->和operator *操作符,因此不可直接通过weak_ptr使用对象,典型的用法是调用其lock函数来获得shared_ptr示例,进而访问原始对象。

标签:std,weak,pa,访问共享,shared,多线程,ptr,指针
From: https://www.cnblogs.com/erichome/p/16944592.html

相关文章

  • 指针处理多维数组的列
    指针处理二维数组的行比较简单,但处理二维数组的列就没那么容易了,因为数组是按行而不是按列存储的。下面的循环对数组a的第i列清零:inta[NUM_ROWS][NUM_COLS],(*p)[NUM_CO......
  • 多线程锁等待超时解决方案
    java.util.concurrent.ExecutionException:org.springframework.dao.CannotAcquireLockException:###Errorupdatingdatabase.Cause:com.mysql.cj.jdbc.exception......
  • 指针实现字符串排序
    题目描述在主函数中输入5个字符串(每个字符串的长度不大于20),并输出这5个字符串。编写一个排序函数,完成对这些字符串按照字典顺序排序。然后在主函数中调用该排序函数,并输......
  • 空指针异常
    对象已经没有了,自然会出现空指针。没有对象了,对象级别的引用和对象级别的方法的调用都会出现空指针异常。......
  • 多线程加锁之后不就是单线程了吗
    突然灵机一动想到:多线程加锁之后不就是单线程了吗,其实在学java的时候老师应该有讲过,但是都忘记了。Q: 多线程lock之后不就是单线程了吗?答:lock并不需要锁定所有的操作......
  • 多线程-基础
    1、继承Thread类​继承Thread必须重写run方法,(具体业务执行方法,需要执行的业务方法,定义在此方法中),注意此方法是线程启动后线程自动调用的;案例publicclassMyThreadext......
  • 函数调用时用const保护指针
    当调用函数并且把指向变量的指针作为参数传入时,通常会假设函数将修改变量(否则,为什么函数需要指针呢?)。例如,如果在程序中看到语句f(&x);大概是希望f改变x的值。但是,f仅需检......
  • JAVA多线程有哪几种实现方式呢?
     下文笔者讲述java中多线程的实现方式,如下所示:JAVA中多线程主要有以下实现方式:1.继承Thread类2.实现Runnable接口3.使用ExecutorService、Call......
  • 两个程序的区别,在于多线程,全局变量中一个线程写入,另一个线程读取,会有脏数据产生
    两个程序的区别 左边程序:一个线程写入时候,另一个线程进行读取,不会读到错误数据右边程序:一个线程写入时候,另一个线程进行读取,会读到中间的数据 ......
  • 【C语言】【指针】输入三个整数,按大小输出
    #include <stdio.h>intmain(){ void exchange(int*p1,int*p2,int*p3); //函数声明// inta,b,c,*p1,*p2,*p3; printf ("Pleaseentera,b,c:\n"); ......