can someone tell me what this code does?
const boost::system::error_code&
i suspect that this code is used to connect to the function via a pointer,
but is it everything what it does?
there is full code:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
void print(const boost::system::error_code&)
{
std::cout<<"hello word\n";
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5));
t.async_wait(&print);
io.run();
return 0;
}
I don't know boost::asio, but I suspect that boost::asio::deadline_timer::async_wait() needs a function taking a single argument of the type const boost::system::error_code&. In order to call async_wait(), you will have to pass a pointer to such a function.
void print(const boost::system::error_code&) is such a function.
If you do not want to use a function argument, you can leave it unnamed. That prevents warnings compilers typically emit when you are not using one of the function arguments provided.
Related
I wrote a little program to launch and record a stereo setup of cameras. I would like to record a sequence of 100ms. The thing is: I don't know how to time the functions with the highest possible precision. I found the header <unistd.h> which includes the function usleep which can pause the execution for a specified microsecond interval. So in my program I'm doing something like this:
left_camera.start_recording();
right_camera.start_recording();
usleep(100000);
left_camera.stop_recording();
right_camera.stop_recording();
Is there a better way to ensure precise timing between the two functions?
You can also use std::this_thread::sleep_for (C++11)
#include <chrono>
#include <thread>
int main()
{
std::this_thread::sleep_for(std::chrono::nanoseconds(500));
}
sleep is not better way to implement a timer. You can use asio asynchronous timer feature from c++ boost library. you can create the timer and this shall call register function after timer expires
#include <iostream>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
void func(const boost::system::error_code&)
{
std::cout << "in func" << std::endl;
}
int main()
{
boost::asio::io_service io;
boost::asio::deadline_timer t(io, boost::posix_time::seconds(0.1));
t.async_wait(&func);
io.run();
return 0;
}
Link libboost_system library while compiling
For more information refer:
https://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/tutorial.html
I am currently trying to get the following application to work:
Await incoming client connection.
Start async. timer in another class.
While the timer runs repeatedly, do other stuff such as async_read and async_write.
Current source code:
#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include <WinSock2.h>
#include <Mswsock.h>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include "TimerClass.hpp"
using namespace boost::asio;
using namespace boost::asio::ip;
TimerClass *timerClass;
void acceptHandler(const boost::system::error_code &errorCode, tcp::socket *socket) {
timerClass = new TimerClass(socket);
timerClass->startTimer();
while(true) {
// Do other suff such as async_write, ...
}
}
int main(int argc, char** argv) {
io_service ioService;
tcp::socket socket(ioService);
tcp::acceptor acceptor{ ioService, tcp::endpoint{ tcp::v4(), 12345 } };
acceptor.listen();
acceptor.async_accept(socket, boost::bind(acceptHandler, _1, &socket));
ioService.run();
return EXIT_SUCCESS;
}
TimerClass.hpp:
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::asio;
using namespace boost::posix_time;
class TimerClass {
public:
TimerClass(ip::tcp::socket *socket);
void startTimer();
void timerHandler(const boost::system::error_code& errorCode);
deadline_timer timer;
};
TimerClass.cpp:
#include <boost/bind.hpp>
#include "TimerClass.hpp"
TimerClass::TimerClass(ip::tcp::socket *socket) : timer(socket->get_io_service(), boost::posix_time::seconds(1)) {}
void TimerClass::startTimer() {
timer.async_wait(boost::bind(&TimerClass::timerHandler, this, boost::asio::placeholders::error));
}
void TimerClass::timerHandler(const boost::system::error_code& errorCode) {
timer.expires_at(timer.expires_at() + boost::posix_time::seconds(1));
timer.async_wait(boost::bind(&TimerClass::timerHandler, this, boost::asio::placeholders::error));
}
Handler Tracking Output:
#asio|1461070492.111630|0*1|socket#000000000021FBD0.async_accept
#asio|1461070498.527997|>1|ec=system:0
Questions:
Why won't it even call async_wait in startTimer? Debugging shows that startTimer gets called but I can't find anything in the Handler Tracking output. Why is that?
Am I correctly passing the socket to the TimerClass?
Without the infinite while(true) loop in the acceptHandler the acceptHandler returns but the application crashes before the io_service properly returns. How is that?
I compiled your code and it works for me (using boost version 1.54).
With your code I get the following output:
#asio|1461081908.437388|0*1|socket#003BFE2C.async_accept
#asio|1461081983.220840|>1|ec=system:0
#asio|1461081983.221817|1*2|deadline_timer#001C1318.async_wait
To make it run properly I had to remove the while(true) on your acceptHandler, obtaining the following output (added a std::cout inside the handler):
#asio|1461083707.104424|0*1|socket#0030FB6C.async_accept
#asio|1461083709.061824|>1|ec=system:0
#asio|1461083709.062803|1*2|deadline_timer#00641318.async_wait
#asio|1461083709.062803|<28158494073611763|
#asio|1461083710.064992|>2|ec=system:0
#asio|1461083710.064992|2|deadline_timer#00641318.cancel
#asio|1461083710.064992|2*3|deadline_timer#00641318.async_wait
TimerHandler executed...
#asio|1461083710.065971|<28169626628843099|
#asio|1461083711.065223|>3|ec=system:0
#asio|1461083711.065223|3|deadline_timer#00641318.cancel
#asio|1461083711.065223|3*4|deadline_timer#00641318.async_wait
TimerHandler executed...
I actually did this test using only the header TimerClass.hpp (defining the methods directly within it -I was lazy-) and it worked like a charm, the problem seems to be when using the .cpp file, that's why I asked if you were using include guards (not the issue though, already tested).
You should consider changing your design approach though, i.e. do not use blocking loops in you handlers, just call another asynchronous operation if needed (like async_read or async_write).
Take a look at this question and corresponding accepted answer for a nice server implementation idea. Or try to adapt some of the boost examples to your needs.
As per the segmentation fault you get when separating declaration from definition in the corresponding header and implementation files, you might want to check this other question.
The following code piece does not compile for me:
#include <iostream>
#include <boost/thread.hpp>
int main(int argc, char* argv[])
{
boost::thread thread(
[]() {
std::cout<<"hello";
}
);
}
With the error :
no matching function for call to ‘boost::thread::thread(main(int, char**)::<lambda()>)’
I feel like I am making a very stupid mistake here, but it has been sometime, and i still fail to find it.
You need to capture io_service by reference to get the above code snippet to compile:
void start_thread(boost::asio::io_service &io_service)
{
boost::thread tcp_thread(
[&io_service]() { // <-- you missed a & here
io_service.run();
}
);
}
Note that the io_service does not implement copy semantics.
I'm trying to pass a namespace function to pthread_create, but compiler is giving me errors, i have googled, searched in stackoverflow, but i couldn't fix my issue:
#include <pthread.h>
#include <iostream>
namespace SBProcThreads
{
void ProcThread(void* defArg)
{
std::cout<<"### :"<<__PRETTY_FUNCTION__<<": ThreadId :"<<(pthread_self())->__sig<<": ###"<<std::endl;
}
}
int main()
{
pthread_t pThreadId;
::pthread_create(&pThreadId,NULL,(void*)&SBProcThreads::ProcThread,NULL);
}
I don't want to pass any arguments, i have even removed void* defArg and tried giving 4th argument in ::pthread_create function, but still it's giving me error.
The function signature for pthread_create requires a function that returns void *. Also, pthread_t returned from pthread_self() should be treated opaquely. Both of these changes are reflected below and compile on my machine:
#include <pthread.h>
#include <iostream>
namespace SBProcThreads
{
void * ProcThread(void* defArg)
{
std::cout<<"### :"<<__PRETTY_FUNCTION__<<": ThreadId :"<<(pthread_self())<<": ###"<<std::endl;
}
}
int main()
{
pthread_t pThreadId;
::pthread_create(&pThreadId,NULL,SBProcThreads::ProcThread,NULL);
}
UPDATE: There are some other issues with your program as well. For example, it's very likely that main will exit before your thread runs. You should join on your thread if you want to make sure it exits first. Using raw pthreads is a great way to learn about threads but can be very very painful compared to some of the pre-existing frameworks out there - try boost::thread or std::thread if you want to just get up and running with as little hassle as possible.
You just need to either declare it so it doesn't need a cast:
void *ProcThread(void* defArg)
pthread_t pThreadId;
::pthread_create(&pThreadId,NULL,SBProcThreads::ProcThread,NULL);
Or cast it to the required form:
int main()
{
pthread_t pThreadId;
::pthread_create(&pThreadId,NULL,(void*(*)(void*))&SBProcThreads::ProcThread,NULL);
}
I'm trying to asynchronously resolve a ftp host using Boost.Asio.
Here's what I've tried so far:
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
using boost::asio::ip::tcp;
class FtpSession {
public:
void Connect(std::string& host) {
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(host, "ftp");
resolver.async_resolve(query,
boost::bind(&FtpSession::OnResolve, this,
boost::asio::placeholders::error,
boost::asio::placeholders::iterator));
}
private:
void OnResolve(const boost::system::error_code& err, tcp::resolver::iterator endpoint_iterator) {
if (!err)
{
std::cout << "resolved!";
}
else
{
std::cout << "error.";
}
}
};
int main() {
FtpSession session;
std::string host("ftp.remotesensing.org");
session.Connect(host);
return 0;
}
But for some reason, when I execute it, it just doesn't print anything:
alon#alon-GA-73PVM-S2H:~/Desktop$ g++ -o test -lboost_system test.cc
alon#alon-GA-73PVM-S2H:~/Desktop$ ./test
alon#alon-GA-73PVM-S2H:~/Desktop$
No errors or warnings at the compilation though.
How can I fix this?
You need to call io_service.run() to actually do the work methinks. Think of the async_resolve as a request in a request queue - you need something (the io_service) to process the requests in the queue, and to do that, you actually need to run() it! In this case, it will see one request, execute it, call the handler and then exit.
Your io_service and ip::tcp::resolver object are going out of scope. Move both of them into members of the FtpSession class, then invoke io_service::run inside of main after session.Connect(host) to start the event loop.
I answered a similar question a few days ago that may help you as well.