问题描述
为了实现一个线程类(在C++98
和Windows.h
中).我有这样的事情:
In order to implement a thread class(In C++98
and Windows.h
). I have something like this:
Thread::Thread(_beginthreadex_proc_type fn)
{
m_raw = fn;
m_args = 0;
m_handle = 0;
m_id = 0;
}
上面的代码工作正常,它接受一个不接收参数的函数,下一个代码它的函数被一个新线程调用:
The code above works fine it takes a function that not receive parameters, and with the next code it function is called by a new thread:
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, m_raw, (m_args ? m_args : 0), 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
此代码也适用于不带任何参数的函数.现在我的问题是关于我如何在 C++98 中接收我的构造函数中的可变参数并保存它们.而且 NO 如果我不需要帮助,我就不能使用现代 C++.所以请不要给我用 c++11 或更高版本实现的解决方案.
This code also works fine with functions that don't take any parameter.Now my question is about how can i in C++98 receive variadic parameters in my constructor and save them.And NO i can't use modern c++ if that was the case I din't need help. So plz don't give me solutions implemented with c++11 or higher.
现在我正在尝试一个 Java 风格的解决方案,因为每个线程都是一个具有名为 Run 的纯虚函数的 IRunnable.而线程几乎就是这个实现与作为一个抽象类的差异.通过这种方式,我可以避免参数,因为我不传递函数而不是我编写另一个继承自 Thread 并实现 Run 的类.代码如下:
Now I'm trying a Java style solution in that every Thread is a IRunnable that have a pure virtual function named Run. And thread is almost the that this implementetation with the diff that is an abstract class. In this way can i avoid parameters because I don't pass the function instead of that I write another class that inherits from Thread and implements Run.The code look like:
struct IRunnable
{
virtual void Run() = 0;
};
线程类
class Thread : public IRunnable
{
HANDLE m_handle;
DWORD m_id;
typedef unsigned (__stdcall *Function)(void*);
_beginthreadex_proc_type m_raw;
void* m_args;
public:
Thread();
~Thread();
Thread(_beginthreadex_proc_type, void*);
Thread(_beginthreadex_proc_type);
unsigned GetId();
virtual void Run() = 0;
void Join();
unsigned int __stdcall call(void*);
};
Call only 是调用 Run 函数成员的包装器
unsigned int __stdcall Thread::call(void* data)
{
Run();
return 0;
}
我的问题在这里:
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, &this->call, 0, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
当我在 vs2019 中编译时,上面的代码产生了下一个错误:
When i compiling in vs2019 the code above produce the next error:
error C2276: '&': 对绑定成员函数表达式的非法操作
error C2660: '_beginthreadex': 函数不接受 5 个参数
推荐答案
如果您查看几乎所有线程库,它们都很少支持发送多个参数;你通常会发送一个指向某物的指针,如果你想要很多东西,你可以创建一个包含很多东西的结构并发送一个指向它的指针.
If you look at pretty much any thread library, they very rarely support sending multiple arguments; you usually send a pointer to something, and if you want many things, you make a struct containing many things and send a pointer to it.
然而,如果你真的想要这个,你可以使用 C varargs 函数来迭代所有可变参数,并用它们分配一个链表,或者分配一个它们的数组,或者任何你想要的其他数据结构.然后,将指向该指针的指针发送到您的线程入口函数.不过,您的函数仍将只使用一个指针.
However, if you really want this, you could use the C varargs functions to iterate over all variadic arguments, and allocate a linked list with them, or allocate an array of them, or whatever other data structure you want. Then, send a pointer to that to your thread entry function. Your function would still be taking just one pointer, though.
在 C 中,没有简单的方法来构造 va_list,这就是可变参数的发送方式.你不能只发送你在主线程上的 va_list ,因为当它到达你的新线程时,该内存不会活着.也没有很好的方法来扩展 va_list 来填充函数参数.
In C, there is no easy way to construct a va_list, which is how variadic arguments are sent around. You can't just send the va_list you have on your main thread, because that memory won't be alive by the time it reaches your new thread. There is also no good way to expand a va_list to fill function arguments.
顺便说一句,我知道您使用的是 C++,但就 C++98 而言,它的可变参数支持与 C 中的基本相同,这就是我在回答中提到 C 的原因.
Btw, I realize you're using C++, but as far as C++98 goes, its varargs support is basically the same as in C, which is why I'm mentioning C in my answer.
这篇关于C++98中如何处理多个不同类型的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!