C++ 使用void将对象正确传递给pthread_create()*
我一直在遵循上的说明,并密切关注它们的示例Pthread Creation and Termination 根据他们的示例,他们将一个C++ 使用void将对象正确传递给pthread_create()*,c++,pthreads,C++,Pthreads,我一直在遵循上的说明,并密切关注它们的示例Pthread Creation and Termination 根据他们的示例,他们将一个long整数值传递给pthread\u create(),这将导致一个类似于此的调用: pthread_create(&thread, NULL, do_something, (long*)testVal); 我要运行的代码的草图是: #include <iostream> #include <pthread.h> using n
long
整数值传递给pthread\u create()
,这将导致一个类似于此的调用:
pthread_create(&thread, NULL, do_something, (long*)testVal);
我要运行的代码的草图是:
#include <iostream>
#include <pthread.h>
using namespace std;
// Simple example class.
class Range {
public:
int start;
int end;
Range(int start_bound, int end_bound) {
start = start_bound;
end = end_bound;
}
void print() {
cout << "\n(" << start << ", " << end << ')';
}
};
void* do_something(void* testVal) {
std::cout << "Value of thread: " << (long)testVal << '\n';
pthread_exit(NULL);
}
int main() {
pthread_t thread;
Range range = Range(1, 2); // What I really want to pass
long testVal = 42; // Let's test
pthread_create(&thread, NULL, do_something, (void*)testVal);
pthread_exit(NULL);
}
运行上述程序将输出“线程值:42”
<>我的C++指针经验是我的几年,但只是为了好玩,让我们把数据类型从<代码>长< /> >改为<代码> int >代码>。这将语句更改为inttestval=42
和std::cout
…但我遇到了一大堆类型错误
这是因为您的范围
类不能从指向void的指针转换
问题如何将范围对象传递给pthread_create()
通过使用间接方式pthread_create
接受指向任何类型对象的指针。这就是void*
的意思;它可以指向任何类型的对象。传递对象的地址:
Range range = Range(1, 2);
Range* range_ptr = ⦥
pthread_create(&thread, nullptr, do_something, range_ptr);
// or shorter
pthread_create(&thread, nullptr, do_something, &range);
您可以将void*
静态强制转换回原始指针类型,然后可以通过指针间接访问指向的对象:
void* do_something(void* void_ptr) {
Range* range_ptr = static_cast<Range*>(void_ptr);
range_ptr->print();
这个例子质量不高。在向线程传递整数时,它使用重新解释技巧来避免间接寻址,但不应将long
重新解释为void*
并返回,因为不能保证它们的大小相同,并且不在64位窗口中,因此标准不能保证它们的往返转换的有效性。该示例应该使用std::intptr\u t
<> P.S.不要在C++中使用<代码> null <代码> >
避免在C++中使用p螺纹。首选std::thread
…但我遇到了一大堆类型错误
这是因为您的范围
类不能从指向void的指针转换
问题如何将范围对象传递给pthread_create()
通过使用间接方式pthread_create
接受指向任何类型对象的指针。这就是void*
的意思;它可以指向任何类型的对象。传递对象的地址:
Range range = Range(1, 2);
Range* range_ptr = ⦥
pthread_create(&thread, nullptr, do_something, range_ptr);
// or shorter
pthread_create(&thread, nullptr, do_something, &range);
您可以将void*
静态强制转换回原始指针类型,然后可以通过指针间接访问指向的对象:
void* do_something(void* void_ptr) {
Range* range_ptr = static_cast<Range*>(void_ptr);
range_ptr->print();
这个例子质量不高。在向线程传递整数时,它使用重新解释技巧来避免间接寻址,但不应将long
重新解释为void*
并返回,因为不能保证它们的大小相同,并且不在64位窗口中,因此标准不能保证它们的往返转换的有效性。该示例应该使用std::intptr\u t
<> P.S.不要在C++中使用<代码> null <代码> >
避免在C++中使用p螺纹。选择std::thread
。在开始手头的任务之前,您需要解决两个基本问题,即将范围的实例传递给新线程
pthread_exit(NULL);
您将在pthread\u exit
的文档中找到关于pthread\u exit()
如何终止调用线程的解释。值得注意的是,在您的程序中,无论如何都不能保证在调用pthread\u exit
之前执行dou something
。pthread\u create
给您的只是一个模糊的承诺,即创建一个新的执行线程,并将很快开始它的业务。不能保证它会在pthread\u create
返回之前开始运行,也不能保证新线程会在pthread\u exit
终止之前运行
那么,让我们假设您正在以某种方式将一个指向范围的指针
对象传递给您的do\u something
。好的,当dou_some
尝试做某事时,实际的范围
对象已经消失,并且您有一个指向已销毁对象的指针,使用它将成为未定义的行为
在main
中,&range
通常为您提供指向此对象的指针,您可以将其转换为void*
并将其传递给pthread_create
;你可以把它转换回一个范围*
并使用它。但在你修复这个未定义的行为之前,这是一个没有实际意义的问题
而不是修复它,您可能会考虑使用<代码> STD::Toe< /Cord>,而不是POSIX线程,它提供了一个更自然的、本地的C++实现线程,实现了这些问题的大部分(当使用正确时).
在开始手头的任务之前,您需要解决两个基本问题,即将范围的实例传递给新线程
pthread_exit(NULL);
您将在pthread\u exit
的文档中找到关于pthread\u exit()
如何终止调用线程的解释。值得注意的是,在您的程序中,无论如何都不能保证在调用pthread\u exit
之前执行dou something
。pthread\u create
给您的只是一个模糊的承诺,即创建一个新的执行线程,并将很快开始它的业务。不能保证它会在pthread\u create
返回之前开始运行,也不能保证新线程会在pthread\u exit
终止之前运行
那么,让我们假设您正在以某种方式将一个指向范围的指针
对象传递给您的do\u something
。好的,当dou_something
尝试做某事时,实际的范围
对象已经消失,并且您有一个指向已销毁对象的指针,并且使用它变得不明确
pthread_exit(NULL);