简体   繁体   English

使用 std::thread & std::bind 在成员 function 中启动线程

[英]Start thread within member function using std::thread & std::bind

I have few queries with respect to below code snapshot.我对下面的代码快照几乎没有疑问。

1) With respect to pthread_create(), assume Thread_1 creates Thread_2. 1) 关于 pthread_create(),假设 Thread_1 创建 Thread_2。 To my understanding Thread_1 can exit without join, but still Thread_2 will keep running.据我了解,Thread_1 可以在不加入的情况下退出,但 Thread_2 仍将继续运行。 Where as in below example without join() I am not able to run thread and I am seeing exceptions.在下面没有 join() 的示例中,我无法运行线程并且我看到异常。

2) In few examples I am seeing thread creation without thread object as below. 2)在几个例子中,我看到没有线程 object 的线程创建如下。 But when I do the same, code is terminated.但是当我这样做时,代码被终止。

std::thread(&Task::executeThread, this);

I am compiling with below command.
g++ filename.cpp -std=c++11 -lpthread

But still it terminate with exception.但它仍然异常终止。 Is this right way of creating thread or is there any different version of C++ (In my project already they are compiling but not sure about the version).这是创建线程的正确方法还是有任何不同版本的 C++ (在我的项目中,他们已经在编译但不确定版本)。

3) In few examples of my project code, I am seeing below way of creating thread. 3)在我的项目代码的几个示例中,我看到了以下创建线程的方式。 But I am not able to execute with below example.但我无法使用下面的示例执行。

std::thread( std::bind(&Task::executeThread, this) );

Below is my code snapshot.下面是我的代码快照。

#include <iostream>
#include <thread>

class Task
{
    public:
    void executeThread(void)
    {
        for(int i = 0; i < 5; i++)
        {
           std::cout << " :: " << i << std::endl;
        }
    }

    void startThread(void);
};

void Task::startThread(void)
{
    std::cout << "\nthis: " << this << std::endl;

#if 1
    std::thread th(&Task::executeThread, this);
    th.join(); // Without this join() or while(1) loop, thread will terminate
    //while(1);
#elif 0
    std::thread(&Task::executeThread, this);  // Thread creation without thread object
#else
    std::thread( std::bind(&Task::executeThread, this) );
    while(1);
#endif
}

int main()
{
    Task* taskPtr = new Task();
    std::cout << "\ntaskPtr: " << taskPtr << std::endl;

    taskPtr->startThread();

    delete taskPtr;
    return 0;
}

Thanks & Regards感谢和问候

Vishnu Beema毗湿奴比玛

std::thread(&Task::executeThread, this); statement creates and destroys a thread object.语句创建和销毁线程 object。 The destructor of std::thread invokes std::terminate when the thread wasn't joined or detached (like in your statement). std::thread的析构函数在线程未加入或分离时调用std::terminate (就像在您的语句中一样)。

There is no good reason to use std::bind in C++11 because lambdas are better in terms of space and speed.没有充分的理由在 C++11 中使用std::bind ,因为 lambda 在空间和速度方面更好。

When building multi-threaded code you need to specify -pthread option when both compiling and linking.在构建多线程代码时,您需要在编译和链接时指定-pthread选项。 Linker option -lpthread is both inadequate and unnecessary. Linker 选项-lpthread既不充分又不必要。

By design, you need to join all the threads you spawned, or detach them.根据设计,您需要加入您生成的所有线程,或将它们分离。 See eg SO question on join/detach请参阅例如关于加入/分离的 SO 问题

See also cppreference, detach另请参阅cppreference,分离

Note also important caveats if main() exits while detached threads are still running 如果 main() 在分离的线程仍在运行时退出,还要注意重要的警告

I also 100% agree with the comment in the other answer about preferring lambdas to bind.我也 100% 同意另一个答案中关于更喜欢绑定 lambda 的评论。

Finally, do not fall for the temptation to do pthread_cancel on a thread in C++.最后,不要陷入在 C++ 中的线程上执行 pthread_cancel 的诱惑。 See egpthread_cancel considered harmful参见例如pthread_cancel 被认为是有害的

  1. In C++ objects have a lifetime.在 C++ 中,对象具有生命周期。 This is a bit different then dealing with handles in C.这与处理 C 中的句柄有点不同。 In C++ if you create an object on the stack in one scope it will be destroyed if you exit that scope.在 C++ 中,如果您在一个 scope 中的堆栈上创建 object,则如果退出 Z31A1FD140BE4BEF2D8ZA11E,它将被销毁。 There are some exception to these rule like std::move , but as a rule of thumb you own the lifetime of an object.这些规则有一些例外,例如std::move ,但根据经验,您拥有 object 的生命周期。

  2. This ties into the same answer as above.这与上述相同的答案有关。 When you called std::thread(&Task::executeThread, this);当你调用std::thread(&Task::executeThread, this); you were actually invoking the thread constructor.您实际上是在调用线程构造函数。 This is the start of the thread life and the object lifetime.这是线程生命周期和 object 生命周期的开始。 Notice that you created this object on the stack.请注意,您在堆栈上创建了此 object。 If you leave the scope {.. yourcode.. } the DTor will be called.如果您离开 scope {.. yourcode.. }将调用 DTor。 Since you have done this before std::move , join or detatch then std::terminate() is called which is raising the exception.由于您在std::movejoindetatch之前完成了此操作,因此调用std::terminate()会引发异常。

  3. You can create a thread that way.你可以这样创建一个线程。 If you look at the linked documentation for std::thread::thread (constructor) there is an example of an object foo being created the same way.如果您查看 std::thread::thread (构造函数)的链接文档,则会以相同的方式创建 object foo 的示例。 What errors are you receiving?你收到什么错误?

Relevant Documentation:相关文档:

a.一个。 std::thread::~thread() std::thread::~thread()

b.湾。 std::thread::thread std::thread::thread

c. c。Lifetime in C++C++ 的使用寿命

I personally would recommend understanding the lifetime of objects in a C++.我个人建议了解 C++ 中对象的生命周期。 In short all objects start their lifetime when their constructor is invoked.简而言之,所有对象的生命周期都是在调用其构造函数时开始的。 When they are killed (as in out of scope) their destructor is called.当它们被杀死(如超出范围)时,它们的析构函数被调用。 The compiler handles this for you so if you're coming from C its a new concept.编译器会为您处理此问题,因此如果您来自 C,它是一个新概念。

Thank you all for your inputs.谢谢大家的意见。 I missed thread object as part of thread creation.作为线程创建的一部分,我错过了线程 object。 Because of this though compiling, I am getting exceptions.因为这个虽然编译,我得到了例外。 Below is my updated code.下面是我更新的代码。 All three scenarios are working fine.所有三种情况都运行良好。

#include <iostream>
#include <thread>

class Task
{
    public:
    void executeThread(std::string command)
    {
        for(int i = 0; i < 5; i++)
        {
            std::cout << command << " :: " << i << std::endl;
        }
    }

    void startThread(void);
    std::thread th2;
    std::thread th3;
};

void Task::startThread(void)
{
    std::cout << "\nthis: " << this << std::endl;

    #if 0
        std::thread th1(&Task::executeThread, this, "Thread1");
        th1.join(); // Without join(), thread will terminate
    #elif 0
        th2 = std::thread(&Task::executeThread, this, "Thread2");
        th2.join();
    #else
        th3 = std::thread( std::bind(&Task::executeThread, this, "Thread3") );
        th3.join();
    #endif
}

int main()
{
    Task* taskPtr = new Task();
    std::cout << "\ntaskPtr: " << taskPtr << std::endl;

    taskPtr->startThread();

    delete taskPtr;
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM