将shared_ptr或unique_ptr传递给_beginthreadex

Passing a shared_ptr or unique_ptr to _beginthreadex

本文关键字:ptr beginthreadex shared unique      更新时间:2023-10-16

我想知道这是否可能。创建一个TestClass类型的shared_ptr或unique_ptr。

然后调用_beginthreadex,并将类的静态方法作为要执行的函数传递给它,并将之前创建的shared_ptr或unique_ptr作为数据传递给它。像这样:

shared_ptr<TestClass> p = make_shared<TestClass>(count, "test");
HANDLE hth1 = (HANDLE)_beginthreadex(NULL, 0, p->ThreadStart,p, 0, NULL);

我通常在没有智能指针的情况下使用这种方法,我通常创建一个TestClass的普通指针,并将TestClass的静态方法和指针本身作为数据传递,然后在静态方法内部将其强制转换为(TestClass*)并运行该类的成员方法等,完成工作,当线程完成时,我删除指针。类似这样的东西:

    TestClass * p = new TestClass(count, "test");
    HANDLE hth1 = (HANDLE)_beginthreadex(NULL, 0, p->ThreadStart,p, 0, NULL);

我想要实现的是使智能指针在线程结束时自动删除对象,因为智能指针将超出范围。

当我按照上面描述的方式进行操作时,编译器会显示以下错误:

"不存在从"std::shared_ptr"到"void*"的合适转换函数"

_beginthreadex看起来像c函数,为了实现您想要的,您需要调用复制构造函数(或者在unique_ptr的情况下调用move)来转移所有权,这在c中是不可能的。

您可以考虑使用std::thread类,它与std套件的其余部分配合得很好。

假设你想运行:

void ThreadStart(std::shared_ptr<TestClass> p);

你可以通过发射

void ThreadStart(std::shared_ptr<TestClass> p)
{
    cout << p->count << " " << p->name << endl;
}
int main()
{
    shared_ptr<TestClass> p = make_shared<TestClass>(33, "test");
    std::thread thr(ThreadStart, p);
    thr.join();
}

std::unique_ptr的情况下,您需要将其std::move到线程函数,因此它实际上会在线程末尾被删除:

void ThreadStart(std::unique_ptr<TestClass> p);
...
unique_ptr<TestClass> p = make_unique<TestClass>(33, "test");
std::thread thr(ThreadStart, std::move(p));

使用shared_ptr::getunique_ptr::get访问指向托管对象的指针。

shared_ptr<TestClass> p = make_shared<TestClass>(count, "test");
HANDLE hth1 = (HANDLE)_beginthreadex(NULL, 0, p->ThreadStart, p.get(), 0, NULL);