从套接字提取数据

data extraction from socket?

本文关键字:数据 提取 套接字      更新时间:2023-10-16

我目前正在以以下方式从套接字中提取数据

            boost::asio::read_until( *socket, buffer, "n", error ); 
            std::string s( (std::istreambuf_iterator<char>(&buffer)), std::istreambuf_iterator<char>());

似乎拉机制很慢,我需要更快地拉更多的数据。我能做些什么来提高性能,有什么建议吗?是否有办法让我创建另一个套接字并将一些提取工作委托给该套接字?

我过去从事过交易应用程序的工作,我可以告诉你,我从未见过任何订单路由系统或实时报价系统实现过搜索"n"的协议。FIX当然不支持这个。这意味着,在您的订单路由或实时报价系统的某个地方,有一个应用程序很可能会接收那些可能使用FIX协议的报价消息,并将它们转换为您现在使用的协议。这很可能至少与系统运行缓慢有关。

如果每个字符串代表一个股票报价,那么我会考虑重新编写广播价格更新的系统,批量发送它们,并且每秒发送它们的次数不超过3 - 5次——假设系统不被自动交易程序使用(这将是一个完全不同的主题,需要一个非常不同的方法)。看起来该应用程序也以ascii文本格式发送引号。我会把它改成二进制格式。FIX支持二进制格式已经有一段时间了,它被称为FAST FIX。自定义二进制协议也是可以接受的。

根据你对股票报价所做的处理类型,我会考虑不将每个报价传递给不同的线程。如果唯一的处理只涉及用新报价更新窗口,则尤其如此。我将传递整个缓冲区(假设它有超过1个引号并且只包含引号)供用户界面线程处理。如果需要完成其他处理,比如将其保存到磁盘或数据库,那么我将有一个单独的线程来处理这种处理。

你没有给我们看太多代码。如果客户端应用程序很慢,那么你可以尝试以下一些改进方法:

  1. 不要动态创建线程。在应用程序开始时创建一个线程池,并根据需要使用它们。要明白太多的线程可能比只有一个线程更糟糕,所以在决定线程数量时,尝试找到一个愉快的平衡。

  2. 与上述相同,尝试只创建一次对象并在需要时重用它们。这可以通过将一组对象存储在vector、堆栈或队列中来实现。仅在以下情况下创建新对象装它们的容器已经用完了。如果你的应用经常使用new操作符在堆上创建对象,这尤其正确。

  3. 在上面的代码中,正如Panasyuk指出的那样,缓冲区可以移动到while循环之外。错误对象也可以。在代码中寻找其他可以只创建一次对象的地方,而不是一次又一次地创建对象。

  4. 理解什么时候需要一个对象的实例。一个静态的。如果多个线程需要对对象进行写操作,则通常需要对象的实例。静态对象可以在只有一个线程的情况下使用,也可以在多个线程只需要从它读取数据的情况下使用。

  5. 当从处理套接字处理的线程向用户界面线程传递消息时,确保使用BeginInvoke而不是Invoke。Invoke是同步的,在继续处理之前将等待被调用的方法完成。BeginInvoke是异步的,会立即返回,所以效率更高。如果应用程序正在丢弃消息并且正在使用Invoke,那么这可能是原因。

  6. 由于应用程序正在使用多个线程,因此可以合理地假设有一些锁对象或语句用于防止多个线程同时执行。查看这些情况,并确保锁在本质上是粒度的——这意味着锁不是为了方便而设置在函数的顶部。将它设置在函数中间只需要它的地方。确保代码也使用临界区而不是互斥锁,因为在Microsoft中,临界区要高效得多。唯一需要使用互斥锁的时候是在将一个DLL附加到两个或多个前执行时,这种情况已经很少发生了。