c++ - 在使用共享指针调用的函数中使用 this 是有效的
问题描述
我有一个关于在 C++ 中使用共享指针和多线程编程的问题。如果我在线程 A 中使用此类的共享指针对象调用成员函数,那么在类中使用 this 属性并将 this 传递到将从线程 B 触发的回调函数中是有效的。从我的角度来看,如果线程A 完成它的工作然后共享指针将过期并且这将是无效的。
使用 shared_from_this 并将其强制转换为 void* 是否有效?
你好这里是代码。这段代码会产生分段错误,对吧?
#include <memory>
#include <iostream>
#include <thread>
#include <unistd.h>
#include "ClassB.h"
class B;
class A
{
public:
A()= default;
void foo(void * ptr)
{
std::cout <<"enter in foo" <<std::endl;
sleep(1);
std::cout << "Thread wake up" << std::endl;
B *pB = reinterpret_cast<B*>(ptr);
pB->x = 5;
}
};
void B::bar()
{
std::cout << "enter in bar" << std::endl;
void * ptr = reinterpret_cast<void *>(this);
auto t2= std::thread(&A::foo,A(),ptr);
t2.detach();
}
void threadTask()
{
std::cout << "ThreadTask" << std::endl;
std::shared_ptr<B> psharedB = std::make_shared<B>();
auto t1 = std::thread(&B::bar,psharedB);
t1.detach();
}
int main()
{
auto t = std::thread(threadTask);
t.join();
sleep(20);
return 0;
}
谢谢乔治
解决方案
如果对象是在堆上分配的( using new
),如果线程完成,它不会变得无效。shared_pointer
存储一个指向堆上实例的指针和一个指向计数变量的指针。如果shared_pointer
被复制,计数变量会增加,如果调用它的析构函数,它会减少。如果计数为 0,则对象的析构函数由共享指针调用,因此如果不再有shared_pointer
s 指向该对象。shared_pointer
应该是线程保存,即使这是非常资源密集型的。重要的是要知道,如果您将指针传递shared_pointer
给shared_pointer
现在负责管理实例,但它不涉及指针的任何其他用法。因此,您不应在指向该对象的其他指针上调用 delete。因此,如果您使用 分配对象,它不应该引起任何冲突new
。
编辑:
这不应该起作用,shared_pointer
因为当线程分离并且范围离开并且count=1
B
应该被销毁时,将被销毁。分离线程总是一个坏主意。
推荐阅读
- python - python imports from file to the system
- javascript - How to specify this in an object literal with flow in js
- c# - Why my list only shows the last value after looping through it?
- typescript - Errors while using Immutable.Map
- react-native - 无法连接到安卓模拟器上的开发服务器
- python - How to find intersection of straight lines with Hough Peaks?
- php - Approach to sending email reminders to users - process
- logstash - logstash - output single event into multiple line output file
- java - Code design: How to ensure that DTO objects refer to the same object, avoid stackoverflow in circular references in Java?
- html - Angular version dispalyed in vendor.js