When I use mutual parameter,'some mutex',in demo of shared data in multi-threading of C ,the two errors occur,and their codes are
C2672:
'invoke': no matching overloaded function found shared_data
C2893:
Failed to specialize function template 'unknown-type std::invoke(_Callable &&) noexcept(<expr>)'
Then I looked the error codes in Microsoft VS Doc,it reads:"To fix this issue, make the template parameter member accessible where it is evaluated.",So what does the sentence mean?Finally,I guess there must be some wrong with the function invoke .
Here's the code:
#include <list>
#include <mutex>
#include <algorithm>
#include<thread>
std::list<int> some_list;
std::mutex some_mutex;
void add_to_list(int new_value)
{
std::lock_guard<std::mutex> guard(some_mutex);
some_list.push_back(new_value);
}
bool list_contains(int value_to_find)
{
std::lock_guard<std::mutex> guard(some_mutex);
return std::find(some_list.begin(), some_list.end(), value_to_find) != some_list.end();
}
int main() {
using std::thread;
thread t1(add_to_list);
thread t2(list_contains);
t1.join();
t2.join();
return 0;
}
So confused that I want to ask for help.
CodePudding user response:
My comment written out as a program :
#include <cassert>
#include <list>
#include <mutex>
#include <algorithm>
#include <future>
// avoid global variable, group related functions in a class
//std::list<int> some_list;
//std::mutex some_mutex;
class my_async_list final
{
public:
void add(const int new_value) // new_value should not change so const
{
// scoped_lock instead of lock_guard https://stackoverflow.com/questions/43019598/stdlock-guard-or-stdscoped-lock
std::scoped_lock<std::mutex> lock{ m_mtx };
m_list.push_back(new_value);
}
bool contains(int value_to_find) const // contains should not change datastructure so it is a const function
{
std::scoped_lock<std::mutex> lock{ m_mtx };
return std::find(m_list.begin(), m_list.end(), value_to_find) != m_list.end();
}
private:
mutable std::mutex m_mtx; // so it can be used in const functions
std::list<int> m_list;
};
int main()
{
my_async_list my_list;
// use lambda functions to launch async function call
auto add_future = std::async(std::launch::async, [&my_list]
{
my_list.add(1);
});
auto contains_future = std::async(std::launch::async, [&my_list]
{
return my_list.contains(1);
});
add_future.get(); // wait until add is done.
bool contains_one = contains_future.get();
assert(contains_one);
return 0;
}