C++ 使用void将对象正确传递给pthread_create()*

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

我一直在遵循上的说明,并密切关注它们的示例Pthread Creation and Termination

根据他们的示例,他们将一个
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 = &range;

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 = &range;

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);