我正在使用一个C ++类库,它提供了用户必须使用的Thread基类
实现run()
方法。
是否有关于如何将参数传递给run()
方法的推荐方法?马上
我更喜欢通过构造函数传递它们(作为指针)。
答案 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等等。)