试着学习asio,我正在关注网站上的例子.
为什么需要io_service,它究竟做了什么?为什么我需要在执行异步操作时将其发送到几乎所有其他函数,为什么它不能在第一次"绑定"后"创建"自身.
有谁知道在哪里可以找到增强错误代码的参考.特别是,异步套接字处理程序?,Google和grepping头文件返回的错误代码已经调整为空.
我在Windows上使用boost :: asio进行了一个非常简单的服务器/客户端性能测试,它似乎表现得非常糟糕.我希望我只是错误地使用该库,并希望得到任何建议.
我有一个会话类,它写一个消息长度,然后写一条消息,然后等待读取消息长度,然后读取一条消息,并一直反复不停地这样做.当我在自己的计算机上本地运行时,我的性能却非常快; 当我在一台计算机上运行服务器而在另一台计算机上运行客户机时,即使在同一网络上,性能也会降低,需要多达1秒才能进行读/写操作.
服务器源代码文件如下:
#include <cstdlib>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
using namespace boost;
using namespace boost::asio;
using namespace boost::asio::ip;
using namespace std;
class Session {
public:
Session(io_service& ioService)
: m_socket(ioService) {}
tcp::socket& GetSocket() {
return m_socket;
}
void StartRead() {
m_messageSizeIterator = reinterpret_cast<char*>(&m_messageSize);
async_read(m_socket, buffer(m_messageSizeIterator, sizeof(m_messageSize)),
bind(&Session::HandleSizeRead, this, placeholders::error,
placeholders::bytes_transferred));
}
void StartWrite(const char* message, int messageSize) {
m_messageSize = messageSize;
m_message = new char[m_messageSize];
memcpy(m_message, message, m_messageSize);
async_write(m_socket, buffer(&m_messageSize, sizeof(int)),
bind(&Session::HandleSizeWritten, this, placeholders::error));
}
void …Run Code Online (Sandbox Code Playgroud) 我在一个中型C/C++项目上工作,我已经应用了Doxygen + Graphviz.它的标题图很有用,但它们只显示基于的关系#include.我有兴趣找到一个(最好是基于linux的)工具,它不仅可以#include根据实际的符号使用情况来分析文件依赖性.例如,这种工具不仅表明a.cpp包括b.h,但a.cpp使用SomeClass的是被声明中c.h包含的b.h.它还能够建议可以修剪的头部包含.
我使用boost ASIO构建了一个C++库.该库需要既是线程安全的又是fork安全的.它有服务调度程序线程,它调用io_service::run().为了支持fork-safety,我已经注册了pre_fork,post_fork_parent和post_fork_child处理程序.该pre_fork()处理程序,调用_io_service.notify_fork(boost::io_service:fork_prepare(),post_fork_parent处理程序调用_io_service.notify_fork(boost::asio::io_service::fork_parent)和post_fork_child电话_io_service.notify_fork(boost::asio::io_service::fork_child).
我fork()遇到的问题是,当发生这种情况时,服务调度程序线程可能处于某个操作的中间,并且可能已获取io_service对象的数据成员的锁定.因此,当我们调用_io_service.notify_fork(boost::asio::io_service::fork_child)它时,子进程看到它们处于相同的状态和post_fork_child()中,它试图获取同一对象的锁,因此无限期地被阻塞(因为子进程中没有线程可以释放解锁).
我在子进程中看到的堆栈跟踪被阻止,是 -
fffffd7ffed07577 lwp_park (0, 0, 0)
fffffd7ffecffc18 mutex_lock_internal () + 378
fffffd7ffecfffb2 mutex_lock_impl () + 112
fffffd7ffed0007b mutex_lock () + b
fffffd7fff26419d __1cFboostEasioGdetailLscoped_lock4n0CLposix_mutex__2t5B6Mrn0D__v_ () + 1d
fffffd7fff2866a2 __1cFboostEasioGdetailQdev_poll_reactorMfork_service6Mn0BKio_serviceKfork_event__v_ () + 32
fffffd7fff278527 __1cFboostEasioGdetailQservice_registryLnotify_fork6Mn0BKio_serviceKfork_event__v_ () + 107
fffffd7fff27531c __1cDdesGtunnelQServiceSchedulerPpost_fork_child6M_v_ () + 1c
fffffd7fff29de24 post_fork_child () + 84
fffffd7ffec92188 _postfork_child_handler () + 38
fffffd7ffecf917d fork () + 12d
fffffd7ffec172d5 fork () + …Run Code Online (Sandbox Code Playgroud) 我已经开始使用Boost.ASIO进行一些简单的网络编程,我对图书馆的理解不是很多,所以请耐心等待我和我的新手问题.
在我的项目中,我只有一个io_service对象.哪个用于所有异步I/O操作等.
我的理解是,可以创建多个线程并将io_service实例的run方法传递给线程,以便为该线程提供更多线程io_service.
我的问题:拥有多个io_service物体是好的设计吗?比方说,例如有2个不同的io_service实例,每个实例有2个线程相关联,它们是否以某种方式相互了解(因此与每个实体合作),或者如果不是,它们会相互产生负面影响吗?
我的目的是io_service为基于套接字的I/O 提供1,为基于串行(tty)的I/O提供另一个.
我经常在代码中看到这种模式,绑定shared_from_this为成员函数的第一个参数,并使用async_*函数调度结果.以下是另一个问题的示例:
void Connection::Receive()
{
boost::asio::async_read(socket_,boost::asio::buffer(this->read_buffer_),
boost::bind(&Connection::handle_Receive,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
Run Code Online (Sandbox Code Playgroud)
使用shared_from_this()而不是使用的唯一原因this是在调用成员函数之前保持对象存活.但除非在某处有某种类型的增强魔法,因为this指针是类型的Connection*,所有都handle_Receive可以,并且返回的智能指针应该立即转换为常规指针.如果发生这种情况,那么没有任何东西可以让对象保持活力.当然,在呼叫中没有指针shared_from_this.
但是,我经常看到这种模式,我不敢相信它在我看来完全被打破了.当操作完成时,是否有一些Boost魔法会导致shared_ptr转换为常规指针?如果是这样,这是在某处记录的吗?
特别是,在某个地方记录共享指针将保持存在直到操作完成?调用get_pointer强指针然后在返回的指针上调用成员函数是不够的,除非强指针在成员函数返回之前不被销毁.
我正在尝试使用boost :: asio创建一个有限的线程池类.但是我被困在某一点可以帮助我.
唯一的问题是我应该减少反击的地方?
代码无法按预期工作.
问题是我不知道我的线程何时完成执行以及我将如何知道它已经返回池中
#include <boost/asio.hpp>
#include <iostream>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/thread/mutex.hpp>
#include <stack>
using namespace std;
using namespace boost;
class ThreadPool
{
static int count;
int NoOfThread;
thread_group grp;
mutex mutex_;
asio::io_service io_service;
int counter;
stack<thread*> thStk ;
public:
ThreadPool(int num)
{
NoOfThread = num;
counter = 0;
mutex::scoped_lock lock(mutex_);
if(count == 0)
count++;
else
return;
for(int i=0 ; i<num ; ++i)
{
thStk.push(grp.create_thread(boost::bind(&asio::io_service::run, &io_service)));
}
}
~ThreadPool()
{
io_service.stop();
grp.join_all();
}
thread* getThread()
{ …Run Code Online (Sandbox Code Playgroud) 我正在使用boost :: asio来做一些非常基本的UDP数据包收集.io_service对象在工作线程中实例化,并且从该线程内部调用io_service.run().我的问题是当我收集数据包时让io_service.run()返回.
我不清楚当停止我的工作线程时,可以从其他线程调用哪些io_service方法.我有一个对io_service对象的引用,并且从另一个线程我进行了这个调用:
ios.dispatch( boost::bind( &udp_server::handle_kill, this ) );
Run Code Online (Sandbox Code Playgroud)
在我的udp_server类中,该函数的处理程序从一个boost :: asio :: ip :: udp :: socket和一个boost :: asio :: deadline_timer对象中取消待处理的工作.两者都有未决的异步工作要做.那时我调用ios.stop():
void udp_server::handle_kill()
{
m_socket.cancel();
m_timer.cancel();
m_ios.stop();
}
Run Code Online (Sandbox Code Playgroud)
由于没有待处理的工作,我希望此时我对ios.run()的调用应该返回 - 但这不会发生.
那为什么不回来呢?对我来说最可能的解释是我不应该从另一个线程调用io_service :: dispatch().但是dispatch()方法似乎只是为了做到这一点 - 在io_service :: run()工作的线程中调度一个函数调用.它似乎就是这样做的.
所以这给我留下了一些相关的问题:
asio对我来说表现很好,但我需要更好地理解这一点架构.
socket :: udp :: cancel()在Win32下的开放套接字上显然是一个不受支持的操作 - 所以这个操作失败了抛出一个异常 - 这实际上导致从io_service :: run()退出,但绝对不是所希望的出口.
socket :: udp :: close()似乎没有取消挂起的async_receive_from()任务,所以调用它而不是socket :: udp :: cancel()似乎将线程留在io_service :: run()中的某个地方.
c++ ×10
boost-asio ×9
boost ×8
asynchronous ×1
c ×1
dependencies ×1
fork ×1
header ×1
libuv ×1
performance ×1
shared-ptr ×1
sockets ×1
threadpool ×1