当前位置: 首页 > 知识库问答 >
问题:

std::线程参数在转换为rvalues后必须是可调用的

宰父焕
2023-03-14

我正在尝试创建2个线程,它们与浮点数组一起工作。Howere编译器给了我这些错误:

/usr/include/c++/9/thread: In instantiation of ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(bool*, float*, float*, float*); _Args = {bool*, float (*)[10], float (*)[10], float (*)[10]}; <template-parameter-1-3> = void]’:
main.cpp:16:66:   required from here
/usr/include/c++/9/thread:120:44: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
  120 |           typename decay<_Args>::type...>::value,
      |                                            ^~~~~
/usr/include/c++/9/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (*)(bool*, float*, float*, float*), bool*, float (*)[10], float (*)[10], float (*)[10]> >’:
/usr/include/c++/9/thread:131:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(bool*, float*, float*, float*); _Args = {bool*, float (*)[10], float (*)[10], float (*)[10]}; <template-parameter-1-3> = void]’
main.cpp:16:66:   required from here
/usr/include/c++/9/thread:243:4: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<void (*)(bool*, float*, float*, float*), bool*, float (*)[10], float (*)[10], float (*)[10]> >::__result<std::tuple<void (*)(bool*, float*, float*, float*), bool*, float (*)[10], float (*)[10], float (*)[10]> >’
  243 |    _M_invoke(_Index_tuple<_Ind...>)
      |    ^~~~~~~~~
/usr/include/c++/9/thread:247:2: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<void (*)(bool*, float*, float*, float*), bool*, float (*)[10], float (*)[10], float (*)[10]> >::__result<std::tuple<void (*)(bool*, float*, float*, float*), bool*, float (*)[10], float (*)[10], float (*)[10]> >’
  247 |  operator()()
      |  ^~~~~~~~
/usr/include/c++/9/thread: In instantiation of ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(float*); _Args = {float (*)[10]}; <template-parameter-1-3> = void]’:
main.cpp:17:43:   required from here
/usr/include/c++/9/thread:120:44: error: static assertion failed: std::thread arguments must be invocable after conversion to rvalues
  120 |           typename decay<_Args>::type...>::value,
      |                                            ^~~~~
/usr/include/c++/9/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (*)(float*), float (*)[10]> >’:
/usr/include/c++/9/thread:131:22:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(float*); _Args = {float (*)[10]}; <template-parameter-1-3> = void]’
main.cpp:17:43:   required from here
/usr/include/c++/9/thread:243:4: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<void (*)(float*), float (*)[10]> >::__result<std::tuple<void (*)(float*), float (*)[10]> >’
  243 |    _M_invoke(_Index_tuple<_Ind...>)
      |    ^~~~~~~~~
/usr/include/c++/9/thread:247:2: error: no type named ‘type’ in ‘struct std::thread::_Invoker<std::tuple<void (*)(float*), float (*)[10]> >::__result<std::tuple<void (*)(float*), float (*)[10]> >’
  247 |  operator()()
      |  ^~~~~~~~

我以为我忘记了dma线程的一些ctor参数,但事实并非如此。下面是我的代码

#include <iostream>
#include <cstdint>
#include <thread>

void dma_service(bool*, float*, float*, float*);
void live_audio(float*);
void live_draw(float*);


    
    constexpr int d_size = 10;
    float data[d_size];
    float pwm_cp[d_size];
    float fft_cp[d_size];
    bool drdy = 0;
    std::thread dma_thrd(dma_service, &drdy, &data, &pwm_cp, &fft_cp);
    std::thread audio_thrd(live_draw, &pwm_cp);


int main(){
    for (auto i = 0; i < d_size; i++)
    {
        data[i] = 0;
        pwm_cp[i] = 0;
    }
    printf("Hello, World!\n");
    drdy = 1;

    int k = 3;
    while(k-->0)
    {
        audio_thrd.join();
        printf("\n\n\n");
        
        for (auto i = 0; i < d_size; i++)
        {
            data[i]++;
        }
        drdy = 1;
    }

}

void dma_service(bool* flag, float* d_array, float* pwm_array, float* fft_array) {
    while (!flag) ;

    for (auto i = 0; i < d_size; i++)
    {
        pwm_array[i] = d_array[i];
        fft_array[i] = d_array[i];
    }

    flag = 0;

}

void live_audio(float* pwm_array) {
    dma_thrd.join();
    printf("Audio Array:\n");
    for (auto i = 0; i < d_size; i++)
    {
        printf("PWM_CP[%d] %f\n", i, pwm_array[i]);
    }
}

我对lambda函数没有太多的经验,所以我不知道这里是否需要它们(并且很乐意避免它们)。谢谢你的建议!

共有1个答案

西门奇希
2023-03-14

给定浮点数据[d_size];&data被推导为“指向数组的指针”类型。与float*参数不匹配。

您可以简单地省略&,那么数组到指针的衰减就会开始,类型就会匹配。

std::thread dma_thrd(dma_service, &drdy, data, pwm_cp, fft_cp);
std::thread audio_thrd(live_draw, pwm_cp);

或者传递第一个元素的地址:

std::thread dma_thrd(dma_service, &drdy, &data[0], &pwm_cp[0], &fft_cp[0]);
std::thread audio_thrd(live_draw, &pwm_cp[0]);

注意,这不足以使程序工作。我发现它缺少线程同步,在全局范围内启动线程是有问题的,因为它们将在main()之前启动。此外,循环中的join()也不能正常工作,因为join()只能执行一次。

 类似资料:
  • 为什么编译器抱怨如果线程函数分层被更改为

  • 我正在尝试使用Python、pygame和OOP从头开始构建一个乒乓球游戏(我知道,这不是使用OOP的最佳语言)。当前具有以下类结构: 游戏对象(对象)| |球(游戏对象)| |桨(游戏对象) 注:球扩展游戏对象 当我试图创建一个球,一个错误显示: 超级(gameDisplay)类型错误:超级()参数1必须是类型,而不是pyplay。表面 有人能帮我吗?

  • 问题内容: 方法getText()必须从UI线程调用,请提供帮助。我是android studio的初学者,可以在网上找到这些代码,但无法弄清楚,我真的很感激。 问题答案: 在其UI线程而非后台线程中获取值。

  • 我有这个代码返回一个错误: 参数必须是实现可数的数组或对象?

  • 看起来它工作得很好,但我想知道我是否必须确保新代码需要线程安全?这里有什么意见吗?抱歉用了假名字,提前致谢。

  • 我不明白为什么当一个被破坏时,它必须处于连接()或分离()状态。 连接等待线程完成,而分离不会。似乎有一些我不理解的中间状态。因为我的理解是连接和分离是互补的:如果我不调用连接(),那么分离()是默认的。 逻辑上的detach()应该是线程的默认行为,因为这是线程的定义,它们是并行执行的,与其他线程无关。 那么,当线程对象被破坏时,为什么要调用terminate()呢?为什么标准不能简单地将线程视