I am trying to create 2 threads, that work with float arrays. Howere compiler gives me these errors:
/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()()
| ^~~~~~~~
I thought that I forgot some ctor arguments for the dma thread but that is not the case. Here is my code:
#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]);
}
}
I don't have much experience with lambda functions so I have no idea if they're needed here (and would be happy to avoid them). Thanks for any suggestions!
Given float data[d_size];
, &data
is deduced as a "pointer to array" type. That won't match a float*
argument.
You can simply omit &
, then array-to-pointer decay will kick in and the types will match.
std::thread dma_thrd(dma_service, &drdy, data, pwm_cp, fft_cp);
std::thread audio_thrd(live_draw, pwm_cp);
Or pass the address of the first element:
std::thread dma_thrd(dma_service, &drdy, &data[0], &pwm_cp[0], &fft_cp[0]);
std::thread audio_thrd(live_draw, &pwm_cp[0]);
Note that this is not sufficient to make the program work. I see it's lacking thread synchronization, and starting threads at global scope like that is problematic because they will start before main()
. Also join()
in a loop won't work correctly, as join()
can be performed only once.
To have matching arguments, you need:
constexpr int d_size = 10;
float data[d_size];
float pwm_cp[d_size];
float fft_cp[d_size];
bool drdy = 0;
void dma_service(bool*, float*, float*, float*);
std::thread dma_thrd(dma_service, &drdy, &data[0], &pwm_cp[0], &fft_cp[0]);
or
constexpr int d_size = 10;
float data[d_size];
float pwm_cp[d_size];
float fft_cp[d_size];
bool drdy = 0;
void dma_service(bool*, float(*)[10], float(*)[10], float(*)[10]);
std::thread dma_thrd(dma_service, &drdy, &data, &pwm_cp, &fft_cp);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.