I'm learning C++ and I have to do some multithreading. Below you'll find code so let me explain it a little bit. We have class Writer that can write to a file and class Reader that can read from a file, of course, many readers can read from the file at the same time but only one Writer can write to file at some moment. Both classes have methods that I want to give to threads. Those methods cannot be static because every object has an id needed in the method.
At this point, I'm completely lost and I have no idea what's wrong.
Here is my code:
#include <iostream>
#include <thread>
#include <shared_mutex>
#include <fstream>
#include <string>
#include <chrono>
#include <vector>
#include <algorithm>
#include <functional>
#include <time.h>
using namespace std;
int getSeconds() {
return rand() % 5 + 1;;
}
class Judge {
public:
shared_mutex decision;
Judge(){}
};
class Reader {
public:
string id;
Reader(string ID) {
id = ID;
}
void Action(fstream &file, shared_mutex &decision) {
string line;
shared_lock<shared_mutex> lock(decision);
this_thread::sleep_for(chrono::seconds(getSeconds()));
while (getline(file, line));
lock.unlock();
if(line.length() < 1) return;
cout << id + line << endl;
}
};
class Writer {
public:
string id;
Writer(string ID) {
id = ID;
}
void Action(fstream &file, shared_mutex &decision) {
int number = rand() % 1000 + 1;
lock_guard<shared_mutex> lock(decision);
this_thread::sleep_for(chrono::seconds(getSeconds()));
file << id + to_string(number) << endl;
}
};
int main()
{
srand(time(NULL));
int num = 5;
vector<thread> threads;
vector<Writer> writers;
vector<Reader> readers;
Judge judge = Judge();
fstream file("dane.txt", ios::app | ios::in);
if(file.is_open()) {
for (int i = 0; i < num; i++)
{
string wID = to_string(0) + to_string(i);
string rID = to_string(1) + to_string(i);
writers.push_back(Writer(wID));
readers.push_back(Reader(rID));
}
for (int i = 0; i < num; i++){
threads[i] = thread(&Writer::Action, writers[i], &file, &judge.decision);
threads[i + num] = thread(&Reader::Action, readers[i], &file, &judge.decision);
}
for(int i = 0; i < num * 2; i++) {
threads[i].join();
}
file.close();
} else {
cout << "Couldn't open file: dane.txt!" << endl;
}
return 0;
}
and here is the complete error given at compilation:
In file included from zad1.cpp:2:0:
/usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >’:
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Writer::*)(std::basic_fstream<char>&, std::shared_mutex&); _Args = {Writer&, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*}]’
zad1.cpp:83:84: required from here
/usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >::_M_invoke(std::thread::_Invoker<std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >::_Indices)’
operator()()
^~~~~~~~
/usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*>]
_M_invoke(_Index_tuple<_Ind...>)
^~~~~~~~~
/usr/include/c++/7/thread:231:4: note: template argument deduction/substitution failed:
/usr/include/c++/7/thread: In substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2, 3}]’:
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Writer::*)(std::basic_fstream<char>&, std::shared_mutex&); _Args = {Writer&, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*}]’
zad1.cpp:83:84: required from here
/usr/include/c++/7/thread:233:29: error: no matching function for call to ‘__invoke(std::__tuple_element_t<0, std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >, std::__tuple_element_t<1, std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >, std::__tuple_element_t<2, std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >, std::__tuple_element_t<3, std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >)’
-> decltype(std::__invoke(_S_declval<_Ind>()...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/tuple:41:0,
from /usr/include/c++/7/bits/unique_ptr.h:37,
from /usr/include/c++/7/memory:80,
from /usr/include/c++/7/thread:39,
from zad1.cpp:2:
/usr/include/c++/7/bits/invoke.h:89:5: note: candidate: template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
/usr/include/c++/7/bits/invoke.h:89:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = void (Writer::*)(std::basic_fstream<char>&, std::shared_mutex&); _Args = {Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*}]’:
/usr/include/c++/7/thread:233:29: required by substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2, 3}]’
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<void (Writer::*)(std::basic_fstream<char, std::char_traits<char> >&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Writer::*)(std::basic_fstream<char>&, std::shared_mutex&); _Args = {Writer&, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*}]’
zad1.cpp:83:84: required from here
/usr/include/c++/7/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_result<void (Writer::*)(std::basic_fstream<char>&, std::shared_mutex&), Writer, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*>’
In file included from zad1.cpp:2:0:
/usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >’:
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Reader::*)(std::basic_fstream<char>, std::shared_mutex); _Args = {Reader&, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*}]’
zad1.cpp:84:90: required from here
/usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >::_M_invoke(std::thread::_Invoker<std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >::_Indices)’
operator()()
^~~~~~~~
/usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*>]
_M_invoke(_Index_tuple<_Ind...>)
^~~~~~~~~
/usr/include/c++/7/thread:231:4: note: template argument deduction/substitution failed:
/usr/include/c++/7/thread: In substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2, 3}]’:
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Reader::*)(std::basic_fstream<char>, std::shared_mutex); _Args = {Reader&, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*}]’
zad1.cpp:84:90: required from here
/usr/include/c++/7/thread:233:29: error: no matching function for call to ‘__invoke(std::__tuple_element_t<0, std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >, std::__tuple_element_t<1, std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >, std::__tuple_element_t<2, std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >, std::__tuple_element_t<3, std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >)’
-> decltype(std::__invoke(_S_declval<_Ind>()...))
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/tuple:41:0,
from /usr/include/c++/7/bits/unique_ptr.h:37,
from /usr/include/c++/7/memory:80,
from /usr/include/c++/7/thread:39,
from zad1.cpp:2:
/usr/include/c++/7/bits/invoke.h:89:5: note: candidate: template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...)
__invoke(_Callable&& __fn, _Args&&... __args)
^~~~~~~~
/usr/include/c++/7/bits/invoke.h:89:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/bits/invoke.h: In substitution of ‘template<class _Callable, class ... _Args> constexpr typename std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&, _Args&& ...) [with _Callable = void (Reader::*)(std::basic_fstream<char>, std::shared_mutex); _Args = {Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*}]’:
/usr/include/c++/7/thread:233:29: required by substitution of ‘template<long unsigned int ..._Ind> decltype (std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with long unsigned int ..._Ind = {0, 1, 2, 3}]’
/usr/include/c++/7/thread:240:2: required from ‘struct std::thread::_Invoker<std::tuple<void (Reader::*)(std::basic_fstream<char, std::char_traits<char> >, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*> >’
/usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Reader::*)(std::basic_fstream<char>, std::shared_mutex); _Args = {Reader&, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*}]’
zad1.cpp:84:90: required from here
/usr/include/c++/7/bits/invoke.h:89:5: error: no type named ‘type’ in ‘struct std::__invoke_result<void (Reader::*)(std::basic_fstream<char>, std::shared_mutex), Reader, std::basic_fstream<char, std::char_traits<char> >*, std::shared_mutex*>’
I have no idea what's wrong, I don't understand these errors.