如何将参数传递给Thread对象?

时间:2009-04-01 11:11:48

标签: c++ multithreading concurrency

我正在使用一个C ++类库,它提供了用户必须使用的Thread基类 实现run()方法。

是否有关于如何将参数传递给run()方法的推荐方法?马上 我更喜欢通过构造函数传递它们(作为指针)。

7 个答案:

答案 0 :(得分:2)

我不确定C ++,但这就是你用Java做的。你有一个扩展Thread(或实现Runnable)的类和一个你想传递参数的构造函数。然后,当你创建新线程时,你必须传入参数,然后启动线程,如下所示:

Thread t = new MyThread(args...);
t.start();

在您的情况下必须相同。

答案 1 :(得分:1)

另一种方法是将此Thread类扩展为仅接受一个functor作为构造函数参数,以便可以绑定其中的任何调用。

然后使用线程的类不需要从Thread继承,但只有一个(或多个)Thread成员。仿函数调用你想要的任何起点(带有任何参数的类的某个方法)

答案 2 :(得分:1)

这是一个典型的模式:

1)定义一个封装线程所需数据的数据结构 2)在主线程中,使用operator new在堆上实例化数据结构的副本。 3)填写数据结构,将指针强制转换为void *,通过线程库提供的任何方式将void *传递给线程过程。 4)当工作线程获得void *时,它将它重新解释为广播到数据结构,然后取得对象的所有权。当线程完成数据时,线程释放它,而不是主线程解除分配它。

以下是您可以编译的示例代码&在Windows中测试。

    #include "stdafx.h"
    #include <windows.h>
    #include <process.h>

    struct ThreadData
    {
        HANDLE isRunning_;
    };

    DWORD WINAPI threadProc(void* v)
    {

    ThreadData* data = reinterpret_cast<ThreadData*>(v);
    if( !data )
        return 0;

    // tell the main thread that we are up & running
    SetEvent(data->isRunning_);

    // do your work here...

    return 1;
}

int main()
{
    // must use heap-based allocation here so that we can transfer ownership
    // of this ThreadData object to the worker thread.  In other words, 
    // the threadProc() function will own & deallocate this resource when it's
    // done with it.
    ThreadData * data = new ThreadData;
    data->isRunning_ = CreateEvent(0, 1, 0, 0);

    // kick off the new thread, passing the thread data
    DWORD id = 0;
    HANDLE thread = CreateThread(0, 0, threadProc, reinterpret_cast<void*>(data), 0, &id);

    // wait for the worker thread to get up & running
    //
    // in real code, you need to check the return value from WFSO and handle it acordingly.  
    // Here I assume the retval is WAIT_OBJECT_0, indicating that the data->isRunning_ event 
    // has become signaled
    WaitForSingleObject(data->isRunning_,INFINITE); 

    // we're done, wait for the thread to die
    WaitForSingleObject(thread, INFINITE);
    CloseHandle(thread);

    return 0;

}

答案 3 :(得分:0)

可以通过构造函数传递它们。请确保指针的活动时间比线程长。

答案 4 :(得分:0)

线程启动的一个常见问题是传递的参数仅存在于调用函数的堆栈中。线程启动通常是延迟的,这样调用函数会返回,并且它只是在线程实际启动后的一段时间 - 此时参数不再存在。

一个解决方案是创建一个事件然后启动线程,将事件作为参数之一传递。然后,启动函数等待事件,当线程完成启动时由线程发出信号。

答案 5 :(得分:0)

您可以将参数作为线程类的成员传递。在线程启动之前,创建线程的线程可能会调用其他方法和/或调用成员函数。因此,它可以填充其工作所需的任何成员。然后,当调用run方法时,它将具有启动所需的信息。

我假设您将为每个线程使用单独的对象。

您通常会将创建的所有线程放入数组,矢量等。

答案 6 :(得分:0)

好吧,我更喜欢将参数放在Start()方法中,因此您可以拥有受保护的构造函数,而不必通过派生类构造函数级联参数。

我会让我的贬低看起来像这样:

class Thread
{
public:
   virtual void Start(int parameterCount, void *pars);
protected:
   Thread();
   virtual void run(int parameterCount, void *pars) = 0;
}

请确保您的参数以某种方式签约,例如#1将是int,#2将是double等等。)