C ++ 11 shared_ptr和pthread

Alsora

我有一个使用APIstd::shared_ptr作为参数的库

我想将这些API与pthreads一起使用。

我正在做的是:从shared_ptr获取原始指针,以便将其传递给pthread。从原始的一个创建一个新的shared_ptr,然后从另一个线程调用我的API。但是double free or corruption,将原始指针转换回共享指针时出现错误。

这是我的代码

#include <memory>
#include <iostream>
#include <thread>
#include <pthread.h>

void* print_task(void* ptr) 
{
    int* val_raw = static_cast<int*>(ptr);
    std::shared_ptr<int> val(val_raw);

    // CALL MY API WHICH TAKES A SHARED_PTR AS ARGUMENT
    std::cout<<"thread job done \n";
}

int main(int argc, char ** argv)
{

   pthread_t thread;

   std::shared_ptr<int> val = std::make_shared<int>(10);
   pthread_create(&thread, nullptr, &print_task, static_cast<void *>(val.get()));

   std::this_thread::sleep_for(std::chrono::seconds(5));

   return 0;
}

我猜我在从共享指针到原始指针的所有转换中都做错了,因为使用std :: threads的相同代码(我可以直接传递shared_ptr)起作用。但是我需要设置线程优先级,因此我正在尝试使用pthreads来实现。

您是否知道如何更改我的代码以便能够传递共享指针并在pthread中使用它?

乌尔里希·埃克哈特(Ulrich Eckhardt)

正如评论中已经提到的那样,问题在于通过原始的void指针传递了共享指针,因此我现在将忽略线程部分:

// this is what we have and what we want to pass to the given function
shared_ptr<some_type> sptr;

// function to somehow pass the shared pointer to
void function(void* ptr);

// As always, when passing anything that doesn't fit into
// the raw pointer, we need to do dynamic allocation:
void* arg = new shared_ptr<some_type>(sptr);

// we can now pass this to the function as intended:
function(arg);

// Note that we give up ownership of the dynamically allocated
// shared pointer instance. Hence, the called function must
// release that object again (it takes ownership). The function
// therefore starts like this:
void function(void* ptr)
{
    // convert the typeless pointer to a typed pointer again
    shared_ptr<some_type>* psptr = static_cast<shared_ptr<some_type>*>(ptr);
    // move the content to a new, local instance
    shared_ptr<some_type> sptr = *psptr;
    // release the dynamically allocated shared pointer again
    delete psptr;
    /// ... code using sptr here ...
}

现在,尽管可以保证可以正常工作,但在某些情况下,这可能不是最佳解决方案:

  • 首先,引用计数器的起伏不是免费的,特别是因为这是以线程安全的,原子的方式完成的。可以避免在函数内部复制共享指针,然后再删除复制的指针。只需将其创建为空实例,然后将其与要复制的指针交换()即可。假设swap()是专门的,这是一个安全的选择,因为它是显而易见的优化,然后归结为交换两个原始指针。该交换不必一定是线程安全的,因此速度更快。
  • 其次,动态分配很昂贵。您可以通过将原始对象的地址传递给函数来避免这种情况和手动释放,但是您必须保证在函数仍在执行时不触摸该对象。特别是对于线程,这需要格外小心。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章