如何将模板函数传递给 POSIX 线程 (pthread)

How to pass template function to POSIX threading (pthread)

我在使用带有 POSIX 线程的模板函数时遇到了麻烦。 作为编程语言,我使用的是 C++98,作为线程基础结构,我使用的是 POSIX 线程 (<pthread.h>).

我的环境不支持标准线程(<thread>)

通常情况下,我们可以像下面这样给pthreads传递参数:

#include <stdio.h>
#include <pthread.h>

void * hello(void *input) {
    printf("%s\n", (char *)input);
    pthread_exit(NULL);
}

int main(void) {
    pthread_t tid;
    pthread_create(&tid, NULL, hello, "hello world");
    pthread_join(tid, NULL);
    return 0;
}

问题是,如何将模板函数和参数传递给 pthreads?

这是示例模板函数:

#include <pthread.h>

template<class T>
void *hello(T val){
    SampleInterface *interface = &T;
    cout << interface->Message<<endl;
}

int main(void) {
    pthread_t tid;
    SampleClass sClass;
    pthread_create(&tid, NULL, hello, sClass);
    pthread_join(tid, NULL);
    return 0;
}

如果我使用上面的用法,我收到两个错误:

error: no matches converting function 'hello' to type 'void* (*)(void*)'
error: candidates are: template<class T> void* hello(T)

由于您没有直接调用hello(),编译器无法为您推导出模板参数,所以您必须显式指定模板参数。

您还需要更改 hello() 以匹配 pthread_create() 期望的签名(就像您的非模板示例所做的那样),除非您在传递的地方对函数进行类型转换pthread_create()(我不建议这样做,因为它在技术上是 未定义的行为,但它在某些编译器中确实有效)。

试试这个:

#include <iostream>
#include <pthread.h>

template<class T>
void *hello(void *arg){
    T *val = static_cast<T*>(arg);
    SampleInterface *interface = val;
    cout << interface->Message << endl;
    return NULL;
}

int main(void) {
    pthread_t tid;
    SampleClass sClass;
    pthread_create(&tid, NULL, hello<SampleClass>, &sClass);
    pthread_join(tid, NULL);
    return 0;
}

或:

#include <iostream>
#include <pthread.h>

typedef void* (*pthread_callback_t)(void*);

template<class T>
void *hello(T *val){
    SampleInterface *interface = val;
    cout << interface->Message << endl;
    return NULL;
}

int main(void) {
    pthread_t tid;
    SampleClass sClass;
    pthread_create(&tid, NULL, reinterpret_cast<pthread_callback_t>(hello<SampleClass>), &sClass);
    pthread_join(tid, NULL);
    return 0;
}

或者,您根本不需要示例中的模板,因此您可以稍微简化代码:

#include <iostream>
#include <pthread.h>

void *hello(void *arg){
    SampleInterface *interface = static_cast<SampleInterface*>(arg);
    cout << interface->Message << endl;
    return NULL;
}

int main(void) {
    pthread_t tid;
    SampleClass sClass;
    SampleInterface *interface = &sClass;
    pthread_create(&tid, NULL, hello, interface);
    pthread_join(tid, NULL);
    return 0;
}

或:

#include <iostream>
#include <pthread.h>

typedef void* (*pthread_callback_t)(void*);

void *hello(SampleInterface *interface){
    cout << interface->Message << endl;
    return NULL;
}

int main(void) {
    pthread_t tid;
    SampleClass sClass;
    SampleInterface *interface = &sClass;
    pthread_create(&tid, NULL, reinterpret_cast<pthread_callback_t>(hello), interface);
    pthread_join(tid, NULL);
    return 0;
}
#include <stdio.h>
#include <pthread.h>
#include <iostream>

struct SampleInterface {
    int Message;
};

struct SampleClass : public SampleInterface {
    SampleClass() {
        Message = 42;
    };
};

template<class T>
void *hello(void* input){
    SampleInterface *interface = (T*) input;
    std::cout << interface->Message << std::endl;
    pthread_exit(NULL);
    return NULL;
}

int main(void) {
    pthread_t tid;
    SampleClass sClass;
    SampleInterface* pInterface = &sClass; //see  Remy Lebeau's comment why we should not pass sClass directly to pthread create
    pthread_create(&tid, NULL, hello<SampleInterface>, (void*) pInterface);
    pthread_join(tid, NULL);
    return 0;
}

编译并运行,尝试将此代码示例粘贴到此处 http://cpp.sh/