如何将boost::shared_ptr作为指针传递给Windows线程函数?

5
如何将boost::shared_ptr作为指针传递给Windows线程函数? 假设以下代码:
test::start()
{
    ....
    _beginthreadex( NULL, 0, &test::threadRun, &shared_from_this(), 0, &threadID );

    ...
    ...
}

/*this is a static function*/
UINT __stdcall test::threadRun( LPVOID lpParam )
{ 
     shared_ptr<test> k = *static_cast< shared_ptr<test>* >(lpParam);
     ...
}

我认为这段代码是不正确的,你有什么想法吗?我该怎么做?

编辑:我通过使用boost::weak_ptr解决了我的问题。请查看我在此页面上的回答。


2
为什么不直接使用 Boost.Thread 呢? - jalf
我有很多使用Windows线程的代码,目前我没有足够的时间将它们转换为boost.Thread。此外,我从未使用过boost.thread。 - Behrouz.M
3
你不需要将它们全部转换。但Boost.Thread是类型安全的,可以直观地处理这个问题。 - jalf
4个回答

3

当你需要从一个类传递参数给静态的函数/方法,并且你拥有一个回调参数(通常在线程回调中使用),我通常会将this传递给回调函数。这样,你只需要进行一次简单的转换,就可以访问类的所有成员。实际上,这个回调函数就像是你类的一个成员:

test::start()
{
    // [...]
    _beginthreadex(NULL, 0, &test::threadRun, this, 0, &threadID);
    // [...]
}

// this is a static function
UINT __stdcall test::threadRun(LPVOID lpParam)
{ 
     test* self = static_cast<test*>(lpParam);

     // do whatever you want with all the instance members :)

     self->getMyShared();
     self->useMyGreatMemberMethof();

     // ...
}

我的意见


1

我通过使用boost::weak_ptr解决了我的问题:

test::start()
{
    ....
    shared_ptr<test> shPtr = shared_from_this();
    boost::weak_ptr<test> wPtr=shPtr;
    _beginthreadex( NULL, 0, &test::threadRun, &wPtr, 0, &threadID );

    ...
    ...
}

/*this is a static function*/
UINT __stdcall test::threadRun( LPVOID lpParam )
{ 
shared_ptr<test> k      = static_cast< boost::weak_ptr<test>* >(lpParam)->lock();
     ...
}

3
这并不能保证解决问题,因为wPtr是在test::start()中的一个局部变量,在test::start()结束后就会失效,所以除非你等待启动的线程在start()退出之前“获取”参数,否则问题与之前相同。 - CashCow

1
你应该使用 reinterpret_cast,并确保在生成期间至少持有一个 shared_ptr。否则,你的对象将被销毁。也就是说,由于你传递了 shared_ptr 指针,你将无法享受通常的指针保护,如果所有现有的 shared_ptr 都被销毁,那么当你的线程被生成时,它将包含一个非法指针。

0

这实际上是一种适用于侵入式引用计数的情况之一。

如果您想传递 boost::shared_ptr,可以将其放入具有侵入式引用计数的结构体中并进行传递。

这是假设您不仅想传递原始指针,并且希望接收线程在完成后删除它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接