So I'm currently using, or at least trying to write a program that makes use of this C pthread threadpool library.
Of note is the following function in thpool.h
:
int thpool_add_work(threadpool, void (*function_p)(void*), void* arg_p);
My code which I'm trying to add a work to is as follows:
int testpool(string (&input)[3]){
// Pass three strings to it. Which we will end up displaying.
cout << input[0].c_str() << endl;
cout << input[1].c_str() << endl;
cout << input[2].c_str() << endl;
return 1;
}
string input[3];
input[1] = "Hello";
input[2] = "Test";
input[3] = "Happy.";
thpool_add_work(thpool, (void*)testpool, (void*)input);
This gives me the following error:
main.cpp: In function 'int main(int, char**)': main.cpp:167:55: error: invalid conversion from 'void*' to 'void (*)(void*)' [-fpermissive] thpool_add_work(thpool, (void*)testpool, (void*)input); ^ In file included from main.cpp:29:0: thpool.h:67:5: note: initializing argument 2 of 'int thpool_add_work(threadpool, void (*)(void*), void*)' int thpool_add_work(threadpool, void (*function_p)(void*), void* arg_p);
I'm certain that I'm simply calling the function wrong or something, but can't figure out how exactly to do it properly. So how do I fix it?
Edit/Update:
I changed the function to do the following:
void testpool(void*){
// Pass three strings to it. Which we will end up displaying.
cout << "Hellooooo." << endl;
}
And this works fine. Now question is how do I pass this an array of strings so I can access the data as arguments?
void (*function_p)(void*)
means that your function MUST have the return type void and takes a single void pointer as argument. This is not the case for your function.
thpool_add_work
expects a pointer to a function that returns void
and takes a single void*
argument. Your testpool
is not such a function. A pointer to testpool
would have the type
int (*)(string (&)[3])
which is quite a bit different than the expected
void (*)(void*)
If you want to use that function with that library, you will need to change it slightly:
void testpool(void* vinput){
string* input = static_cast<string*>(vinput);
// Pass three strings to it. Which we will end up displaying.
cout << input[0].c_str() << endl;
cout << input[1].c_str() << endl;
cout << input[2].c_str() << endl;
}
Note that I've changed the argument type, added a cast to string*
, and removed the return
statement. Now you can call thpool_add_work
like this:
thpool_add_work(thpool, testpool, input);
If you really need that return value, you'll need to go one step further and pass a pointer to some struct:
struct TestpoolArgs
{
string input[3];
int ret;
};
void testpool(void* vargs){
TestpoolArgs* args = static_cast<TestpoolArgs*>(vargs);
// Pass three strings to it. Which we will end up displaying.
cout << args->input[0].c_str() << endl;
cout << args->input[1].c_str() << endl;
cout << args->input[2].c_str() << endl;
args->ret = 1;
}
With this version, your call site would look something like this:
TestpoolArgs args;
args.input[0] = "Hello";
args.input[1] = "Test";
args.input[2] = "Happy.";
thpool_add_work(thpool, testpool, &args);
// Wait until testpool runs somehow
int testpool_return_value = args.ret;
One last note is that keeping your argument objects alive until an asynchronous call completes could be a challenge. Declaring them as automatic variables as I've done here means that you have to wait for the asynchronous call to complete before you exit the scope in which they're declared, and you can't really use std::unique_ptr
or std::shared_ptr
with a C library. You're likely better off using something like std::async
since you're writing C++.
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.