在不超出范围的情况下将指针传递到线程

Passing pointers to threads without being out of scope

本文关键字:指针 线程 情况下 范围      更新时间:2023-10-16

我得到了一个预定义的类/函数的预定义.lib文件。

我需要创建一个:

    Cdefined *p = new Cdefined;
    p->Init();

在 main() 程序中,在调用我的线程之前初始化我的类对象。

但是,我

意识到在我的每个线程中,我都必须调用:

    p->doProcess(); 

为每个线程运行一段代码。

但是,除非我调用p->Init(),否则此功能将不起作用。

既然现在我至少有 2 个 p 作用域(一个在 main() 中创建,其中 N 个在 N 个线程中创建),我该如何设计我的线程,以便可以在没有作用域错误的情况下传入类?[我的限制是p->Init()必须被召唤main()]

如果对象的生存期只是绑定到 main 的范围,那么这很容易 - 只需确保在销毁对象之前已停止并连接所有线程即可。这可以通过使用范围在 main 范围内的智能指针管理对象来更好地实施,或者更简单地说,通过在 main 内为对象提供自动生存期:

void thread_func(Cdefine *);
int main()
{
    Cdefine thing;
    thing.Init();
    std::thread thread1(thread_func, &thing);
    std::thread thread2(thread_func, &thing);
    // do stuff
    thread1.join();
    thread2.join();
    // Now it's safe to destroy the object
}

在更复杂的情况下,您不能简单地将对象绑定到比线程更广泛的范围,您可以考虑使用 std::shared_ptr 来管理它(如果您坚持使用 2011 年之前的语言,则可以使用 std::tr1::shared_ptrboost::shared_ptr)。例如:

void thread_func(std::shared_ptr<Cdefine> p);
void spawn_threads()
{
    std::shared_ptr<Cdefine> p = std::make_shared<Cdefine>();
    p->Init();
    std::thread thread1(thread_func, p);
    std::thread thread2(thread_func, p);
    thread1.detach();
    thread2.detach();
    // The threads can carry on doing their thing, and it's safe to
    // drop our shared pointer. The object will be deleted when the
    // last thread drops its pointer to it.
}

顺便说一句,为什么在构造对象后需要调用Init函数?为什么不在构造函数中初始化它,因为这就是构造函数的用途?

为每个

线程创建一个Cdefined实例,调用其Init方法,并将其作为参数传递给线程。

像这样:

for (int i = 0; i < NUM_THREADS; i++)
{
    Cdefined *p = new Cdefined;
    p->Init();
    create_thread(thread_func, p);
}

和线程功能:

void *thread_func(void *data)
{
    Cdefine *p = reinterpret_cast<Cdefine*>(data);
    for (;;)
    {
        // Do stuff...
        p->doProcess();
        // Do other stuff
    }
    return 0;
}