如何将参数传递给线程对象? 我正在使用C++类库,它提供了用户必须使用的线程基类。 实现run()方法
关于如何将参数传递给如何将参数传递给线程对象? 我正在使用C++类库,它提供了用户必须使用的线程基类。 实现run()方法,c++,multithreading,concurrency,C++,Multithreading,Concurrency,关于如何将参数传递给run()方法,是否有推荐的方法?马上 我更喜欢通过构造函数(指针)传递它们。 我不确定C++,但这就是java中的方法。您将拥有一个扩展Thread(或实现Runnable)的类和一个具有您希望传递的参数的构造函数。然后,在创建新线程时,必须传入参数,然后启动线程,如下所示: Thread t = new MyThread(args...); t.start(); class Thread { public: virtual void Start(int param
run()
方法,是否有推荐的方法?马上
我更喜欢通过构造函数(指针)传递它们。 我不确定C++,但这就是java中的方法。您将拥有一个扩展Thread(或实现Runnable)的类和一个具有您希望传递的参数的构造函数。然后,在创建新线程时,必须传入参数,然后启动线程,如下所示:
Thread t = new MyThread(args...);
t.start();
class Thread
{
public:
virtual void Start(int parameterCount, void *pars);
protected:
Thread();
virtual void run(int parameterCount, void *pars) = 0;
}
必须与您的情况相同。可以通过构造函数传递它们。只需确保指针的寿命比线程长。线程启动的一个常见问题是,传递的参数仅存在于调用函数的堆栈上。线程启动通常是延迟的,因此调用函数返回,而线程实际启动只是在一段时间之后——此时参数不再存在
一种解决方案是创建一个事件,然后启动线程,将事件作为参数之一传递。然后,启动函数等待事件,该事件在完成启动后由线程发出信号。您可以作为thread类的成员传递参数。创建线程的线程可以在线程启动之前调用其他方法和/或调用成员函数。因此,它可以填充它工作所需的任何成员。然后,当调用run方法时,它将具有启动所需的信息 我假设您将为每个线程使用一个单独的对象
通常,您会将创建的所有线程放入数组、向量等中。好吧,我更喜欢将参数放入Start()方法中,这样您就可以拥有一个受保护的构造函数,而不必通过派生类构造函数级联参数 我很乐意让我的失语症看起来像这样:
Thread t = new MyThread(args...);
t.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等:)另一种方法是扩展此线程类以接受函子作为唯一构造函数参数,以便可以绑定其中的任何调用
这样,使用线程的类就不需要从线程继承,而只需要有一个(或多个)线程成员。functor调用您想要的任何起点(类的某个方法具有任何参数)以下是一个典型的模式: 1) 定义一个数据结构,封装线程所需的所有数据 2) 在主线程中,使用运算符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;
}
#包括“stdafx.h”
#包括
#包括
结构线程数据
{
手柄正在运行;
};
DWORD WINAPI threadProc(void*v)
{
螺纹数据*数据=重新解释铸件(v);
如果(!数据)
返回0;
//告诉主线程我们正在启动和运行
设置事件(数据->正在运行);
//在这里做你的工作。。。
返回1;
}
int main()
{
//这里必须使用基于堆的分配,以便我们可以转移所有权
//将此ThreadData对象的,
//threadProc()函数将拥有并释放此资源
//完了。
ThreadData*data=新的ThreadData;
数据->isRunning_u2;=CreateEvent(0,1,0,0);
//启动新线程,传递线程数据
dwordid=0;
HANDLE thread=CreateThread(0,0,threadProc,reinterpret_cast(数据),0,&id);
//等待工作线程启动并运行
//
//在实际代码中,您需要检查WFSO的返回值并进行相应的处理。
//这里我假设retval是WAIT\u OBJECT\u 0,表示data->isRunning\u事件
//已经发出了信号
WaitForSingleObject(数据->正在运行,无限);
//我们做完了,等线死吧
WaitForSingleObject(线程,无限);
闭柄(螺纹);
返回0;
}
使用getter方法的方法很好,但我想我更喜欢通过线程构造函数传递参数。我喜欢在调用构造函数后让一个对象可用。我从未尝试过。让我吃惊的是,当工作负载变化时,你必须改变池中的线程数量,这似乎是一个棘手的复杂问题。哈,java回答被C++标记的问题所接受:这当然不是这个问题的答案。