C++ Compilation error about running io_context in different thread - c++

I am trying to use the asio::io_context in multiple threads.
#include <iostream>
#include <vector>
#include <asio.hpp>
#include <thread>
#include <future>
#include <functional>
int main()
{
asio::io_context ctx;
std::vector<std::future<asio::io_context::count_type>> tasks;
for(int i = 0; i < 3; ++i)
{
tasks.push_back(std::async(std::launch::async, std::bind(&asio::io_context::run, &ctx));
}
for(auto &task: tasks){tasks.get();}
return 0;
}
However, I am getting a compilation error
asio_blah.cpp: In function ‘int main()’:
asio_blah.cpp:101:94: error: no matching function for call to ‘bind(<unresolved overloaded function type>, asio::io_context*)’
tasks.push_back(std::async(std::launch::async, std::bind(&asio::io_context::run, &ctx));
Not sure whey the compiler is not able to figure the member function pointer ( I believe the member func type is asio::io_context::count_type (asio::io_context*)() and the function signature should visible to the compiler since asio.hpp is included) and report the error unresolved overloaded function type.
Any suggestions to fix the error?

You may go for lambda something like this:
#include <iostream>
#include <vector>
#include <boost/asio.hpp>
#include <thread>
#include <future>
#include <functional>
using namespace boost;
int main()
{
asio::io_context ctx;
std::vector<std::future<asio::io_context::count_type>> tasks;
for(int i = 0; i < 3; ++i)
{
tasks.push_back(std::async(std::launch::async, [&ctx]() {
return ctx.run();
}));
}
for(auto &task: tasks){task.get();}
return 0;
}
Edit:
As rightly said by Miles Budnek, io_context::run has multiple overloads. You cannot take a pointer to it without forcing overload resolution with a cast.
If you really want to use std::bind, go for casting.
My opinion is same as that of others. GO FOR LAMBDA!!!

Related

Using boost::asio::post for a function that takes in parameters

I'm new to using boost, and threadpools. I want to pass a function to a threadpool that takes a variable as a parameter. In this simple example I'm just passing in an integer. My understanding is post is going to call an available thread in the thread pool to do something. The code compiles if I set up printProduct to not take in any variables, but that's not what I'm eventually trying to do.
References to relevant documentation would be very helpful (I haven't successfully found much discussion of boost::asio::post), as well as advice on how to solve the problem. Thanks!
#include <cstdlib>
#include <iostream>
#include <pthread.h>
#include <boost/version.hpp> // version is 1.72
#include <boost/asio.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/thread_pool.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/asio/post.hpp>
#include <boost/lockfree/queue.hpp>
using namespace std;
int printProduct(int endval){
// int endval = 1000000;
int prod = 1;
for (int i=0;i<endval;i++){
prod = prod * i;
}
return prod;
}
int main() {
boost::asio::thread_pool tp(8);
for (int i =0; i<200; i++){
// issue is how to pass the parameter into post
boost::asio::post(tp, printProduct,i);
// boost::asio::post(tp, printProduct(i));
}
}
boost::asio::post takes any callable object. Requirements for such object you can find here.
There are many ways to achive what you want:
[1] lambda expressions
boost::asio::post(tp, [i]{ printProduct(i); });
[2] bind
boost::asio::post(tp, std::bind(printProduct,i));
[3] custom functor class
struct Wrapper {
int i;
Wrapper(int i) : i(i) {}
void operator()() {
printProduct(i);
}
};
boost::asio::post(Wrapper{i});

Xcode C++ Vectors: Implicit instantiation of undefined template

I ran this code on a different IDE and it was successful. For some reason I get the above error message on Xcode. I assume I'm missing a header of some kind, but I'm not sure which one.
#include <iostream>
#include <limits>
#include <string>
#include <vector>
int main() {
vector<string> listRestaurants; // error: Implicit instantiation of undefined template
return 0;
}
Xcode 10.2.1 was showing me the error
Implicit instantiation of undefined template 'std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >'.
#include <iostream>
#include <vector>
int main(int argc, const char * argv[]) {
std::vector<std::string> listRestaurants;
....
return 0;
}
Fixed my issue.
If adding std:: is not the issue for you, then check if you have #include <vector>. That fixed the issue for me.
Didn't realize that #include <vector> is required. I thought it was part of standard library template; I ran this code in VSCODE IDE and it worked fine for me
#include <iostream>
#include <vector>
using namespace std;
int main()
{
uint_least8_t i; // trying to be conscious of the size of the int
vector<int> vect;
for(i = 0; i < 5; ++i)
{
vect.push_back(i);
}
for(auto i : vect)
{
cout << i << endl;
}
return 0;
}
From the comments:
The std namespace houses both of those templates. Change vector to std::vector, and string to std::string. – WhozCraig
the vector and string were placed in the namespace std
using namespace std;

call_once to initialize a function

I am trying to initialize a function using call_once(...). My program is giving me the compiling error 'std::once_flag::once_flag(const std::once_flag&)': attempting to reference a deleted function. I don't understand why the function is deleted.
#include "stdafx.h"
#include <string>
#include <thread>
#include <future>
#include <cstdio>
#include <iostream>
#include <queue>
#include <condition_variable>
using namespace std;
once_flag flagZero;
string printerFunc(queue<char>& input, once_flag& flag){
string output = "";
function<void(string&)> f;
call_once(flag, [&](){
f = [&](string& output){}; });
f(output);
return output;
}
int _tmain(int argc, _TCHAR* argv[])
{
string input = "0102030";
queue<char> inputQueue;
for(char c : input){
inputQueue.push(c);
}
auto zeros = async(printerFunc, ref(inputQueue), flagZero);
this_thread::sleep_for(chrono::seconds(10));
return 0;
}
My program is giving me the compiling error
std::once_flag::once_flag(const std::once_flag&): attempting to
reference a deleted function.
This is a copy constructor:
std::once_flag::once_flag(const std::once_flag&)
As per the documentation: std::once_flag is neither copyable nor movable. This is enforced by ensuring that the relevant constructors and assignment operator functions are deleted.
Just as with std::thread the arguments are passed by value.
To pass them by reference and to ensure that flagZero is not copied wrap it in std::ref and pass it as follows: std::async(printerFunc, ref(inputQueue),std::ref(flagZero));

Error: more than one instance of overloaded function "Datafrompeer" matches the argument list

I get the following error when compiling my code below:
error:more than one instance of overloaded function "Datafrompeer"
matches the argument list
What can I do to resolve this?
#include <stdio.h>
#include <string.h>
#include <WinSock2.h>
#include <conio.h>
int Datafrompeer(char* SERVER_ADDRESS_STR,int SERVER_PORT,FILE * fileptr)
{
}
void main()
{
char* IPstr=NULL;
int Portnum;
FILE* SharedFilesList=NULL;
Datafrompeer(IPstr,Portnum,SharedFilesList);
}

Boost thread example show error it's cannot matching function for call to 'boost::thread::thread(<unresolved overloaded function type>)'

I'm initialized thread on main function when created namspace multithread_init in order to push set_multihthread class to namespace. Why after declared boost::thread it's not matching function for call boost::thread t(smulti.thread)?
#define BOOST_THREAD_USE_LIB
#include <boost/thread.hpp>
#include <boost/thread/thread.hpp>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <iostream>
#ifndef MULTITHREAD_INIT_HPP_
#define MULTITHREAD_INIT_HPP_
namespace multithread_init{
class set_multithread{
private:
//t;
public:
void thread(){
for(int i = 0; i < 5; i++){
wait(1);
std::cout<<" thread i value : "<<i<<std::endl;
}
}
void wait(int seconds)
{
boost::this_thread::sleep(boost::posix_time::seconds(seconds));
}
// void multi_case(){
// t.join();
// boost::thread t(thread);
// }
};
}
#endif /* MULTITHREAD_INIT_HPP_ */
main file follow as below.
int main()
{
/*thread */
multithread_init::set_multithread smulti;
boost::thread t(smulti.thread);
t.join();
}
You can't pass a member function that way. You need to bind it to the object
boost::thread t(boost::bind(&multithread_init::set_multithread::thread, &smulti));