从 'void* (*)(int*)' 到 'void* (*)(void*)' 的无效转换

Posted

技术标签:

【中文标题】从 \'void* (*)(int*)\' 到 \'void* (*)(void*)\' 的无效转换【英文标题】:invalid conversion from 'void* (*)(int*)' to 'void* (*)(void*)'从 'void* (*)(int*)' 到 'void* (*)(void*)' 的无效转换 【发布时间】:2021-03-15 07:36:48 【问题描述】:

我正在尝试计算多线程 C++ 程序来计算前 N 个整数的立方和。

每个线程应该计算一个部分和以平均分配它们之间的工作。 与 pthread_create 参数斗争它给出了错误。


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

#define n 6
#define p 4

using namespace std; 

int part = 0; 
int arr[] =  1,2,3,4,5,6 ;
int sum[p]=0;
void* cube_array(int arr[]) 
 

    int thread_part = part++; 

    for (int i = thread_part * (n/ p); i < (thread_part + 1) * (n/ p); i++) 
        sum[thread_part] += arr[i]*arr[i]*arr[i]; 
        

        return NULL;
 

// Driver Code 
int main() 
 

    pthread_t threads[p]; 


    for (int i = 0; i < p; i++) 
        pthread_create(&threads[i], NULL, cube_array, (void*)NULL); 

    for (int i = 0; i < p; i++) 
        pthread_join(threads[i], NULL); 

    int total_sum = 0; 
    for (int i = 0; i < p; i++) 
        total_sum += sum[i]; 

    cout << "sum is " << total_sum << endl; 

    return 0; 
 

【问题讨论】:

这能回答你的问题吗? Casting a function pointer to another type 【参考方案1】:

根据docs,pthread_create()的签名是

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

所以你传递的函子应该接收到 arg void*(现在你正在接收 int*)。 所以只需将 arg 类型更改为void*,并在函数内部将其转换为int*,所以它看起来像这样:

void* cube_array(void* temp_arr) 
 
    int* arr = (int*)temp_arr;
    
    int thread_part = part++; 

附:你应该从 pthread 切换到 std::threadstd::future

【讨论】:

执行此操作后显示错误无效转换从 'void* ()(void*)' 到 'void* ()(void)' @ShivamMishra 这个ans2er 是正确的,所以你在尝试将它应用到你的代码时一定做错了,但我们看不到你尝试了什么。【参考方案2】:

自 c++11 标准起,标准库中就有线程支持,因此您可以使用 std::thread 代替 pthread。它对不同的线程函数签名没有问题,但对您需要的任何函数变体都有很好的支持。

#include <iostream> 
#include <thread>
#include <deque>
#include <algorithm>

#define n 6
#define p 4

using namespace std; 

int part = 0; 
int arr[] =  1,2,3,4,5,6 ;
int sum[p]=0;
void cube_array(int arr[], int thread_part) 

    for (int i = (thread_part * n) / p; i < ((thread_part + 1) * n) / p); i++) 
        sum[thread_part] += arr[i]*arr[i]*arr[i]; 
        
 

// Driver Code 
int main() 
 

    std::deque<std::thread> threads; 


    for (int i = 0; i < p; ++i) 
        threads.emplace_back(std::thread(cube_array, arr, part++)); 

    for (int i = 0; i < threads.size(); ++i) 
        threads[i].join(); 

    int total_sum = 0; 
    for (int i = 0; i < p; i++) 
        total_sum += sum[i]; 

    cout << "sum is " << total_sum << endl; 

    return 0; 
 

【讨论】:

是的,谢谢。它解决了这个问题,但我的答案仍然不正确。是不是我的逻辑有问题。 @ShivamMishra 与(n/p) 的拆分是不正确的,因为它只为每个线程提供一个元素。您应该使用thread_part*n/p(thread_part+1)*n/p(在乘法之后除)。 std::min(...) 没用,因为thread_part 的最大值是p-1,那么(thread_part+1)*n/p 不会超过n

以上是关于从 'void* (*)(int*)' 到 'void* (*)(void*)' 的无效转换的主要内容,如果未能解决你的问题,请参考以下文章

qsort 给出 [错误]:从 `int (*)(cricketer*, cricketer*)' 到 `int (*)(const void*, const void*)' 的无效转换

如何使用静态多态性在 int 和指针类型之间进行转换?

为啥我可以将 static_cast void* 转换为 int* 而不能转换为 int*&?

使用 malloc(sizeof()) 从 *void 到 *int [-fpermissive] 的无效转换

java包名的约定,如Dao,vo,之类,谁能告诉我尽量多的这些约定啊?

int main (void) __attribute__ ((weak, alias ("alt_main")));嘛意思