【问题标题】:How to use std::thread?如何使用 std::thread?
【发布时间】:2015-04-23 05:12:08
【问题描述】:

当我像这样使用std::thread 时:

func()
{
   std::thread(std::bind(&foo, this));
}

线程对象在堆栈中分配,并在func() 返回时被销毁。 所以我尝试像这样使用它:

func()
{
   std::thread* threadPtr = new std::thread(std::bind(&foo, this));
}

我应该在哪里delete threadPtr? 以及如何创建一个最初被挂起的线程?

【问题讨论】:

  • "我应该在哪里删除 threadPtr?" 这取决于你,但你没有句柄可以在函数内部以外的任何地方删除它。
  • 您实际上想要完成什么?如果您告诉我们您要解决的具体问题,我们或许可以为您提供更好的建议。

标签: c++ multithreading stdthread


【解决方案1】:

如果希望线程独立运行,则需要在对象上使用detach() 方法。否则,如果对象在线程仍在运行时被销毁,thread 析构函数将终止您的程序。

线程一创建就开始运行。您不能创建处于挂起状态的线程对象。您可以存储参数来创建线程而不是实际创建它(例如,可能使用std::function),或者让它在互斥锁或条件变量上阻塞,直到您准备好让它运行为止。

【讨论】:

  • 所以代码应该是auto threadObj = std::thread(std::bind(&foo, this)); threadObj.Detach()?
  • @Zach 取决于您的线程正在做什么,detach 可能不合适(例如,如果它访问在线程仍在执行时被销毁的对象的资源)。
  • @Zach 他们指的是std::thread::detach
  • @James Adkison,谢谢。 detach() 是我想要的。
【解决方案2】:

如何使用std::thread?

这取决于您在线程中所做的事情,但很可能您会想要使用join。也可以使用detach,但必须注意确保它不使用任何可能在执行时被破坏的资源。

std::thread(std::bind(&foo, this));

这没有任何意义。您正在绑定(不需要使用 bindthis 指针,但 &foo 不是指向成员函数的指针(看起来像 &Foo::foo)。假设您打算使用指向成员函数的指针,这意味着 func 也是同一类的成员函数(即,因为它可以访问 this 指针)因此以下代码为您提供了一个示例你可以

示例代码

#include <iostream>
#include <thread>

class Foo
{
public:
    Foo() = default;

    ~Foo()
    {
        if (mThread.joinable())
        {
            mThread.join();
        }
    }

    void foo()
    {
        std::cout << "Foo::foo\n";
    }

    void func()
    {
        if (mThread.joinable())
        {
            mThread.join();
        }

        // Creates the thread without using 'std::bind'
        mThread = std::thread(&Foo::foo, this);
    }

private:
    std::thread mThread;
};

int main()
{
    {
        Foo f;
        f.func();
        f.func();
    }

    return 0;
}

示例输出

Foo::foo
Foo::foo

我应该在哪里删除 threadPtr?

我不会动态分配线程,但在上面的示例代码中你会在加入后删除它。

如何创建一个最初被挂起的线程?

C++ 不直接支持此功能,但您可以通过std::thread::native_handle 使用特定于平台的 API。 注意,如果您只想在一开始就阻塞一次,您可以使用同步原语来实现这一点(例如,在运行实际线程之前阻塞 std::mutex)。

【讨论】:

    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多