如何使用boost.thread运行多个接收器,每个线程应该分配给每个接收器?


#include <iostream>
#include <time.h>
#include <chrono>
#include <ctime>
#include <string>
#include <boost/asio.hpp>
#include "boost/bind.hpp"
#include <string>
#include <bits/stdc++.h> 
#include <thread>
#include <boost/thread.hpp>
using namespace std; 
using boost::asio::io_service;

const short multicast_port = 30001;
class receiver
{
public:
receiver(boost::asio::io_service& io_service,
const boost::asio::ip::address& listen_address,
const boost::asio::ip::address& multicast_address)
: socket_(io_service)
{
// Create the socket so that multiple may be bound to the same address.
boost::asio::ip::udp::endpoint listen_endpoint(
listen_address, multicast_port);
socket_.open(listen_endpoint.protocol());
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.bind(listen_endpoint);
// Join the multicast group.
socket_.set_option(
boost::asio::ip::multicast::join_group(multicast_address));
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
boost::bind(&receiver::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_receive_from(const boost::system::error_code& error,
size_t bytes_recvd)
{
if (!error)
{
std::cout.write(data_, bytes_recvd);
std::chrono::time_point< std::chrono::system_clock > now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
auto nanoseconds = std::chrono::duration_cast< std::chrono::nanoseconds >( duration );
std::cout<<" "<<boost::this_thread::get_id()<<" "<<nanoseconds.count() << " nanoseconds "<<std::endl;

socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
boost::bind(&receiver::handle_receive_from, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
private:
boost::asio::ip::udp::socket socket_;
boost::asio::ip::udp::endpoint sender_endpoint_;
enum { max_length = 1024 };
char data_[max_length];
};
int main(int argc, char* argv[])
{
try
{
if (argc != 3)
{
std::cerr << "Usage: receiver <listen_address> <multicast_address>n";
std::cerr << "  For IPv4, try:n";
std::cerr << "    receiver 0.0.0.0 239.255.0.1n";
std::cerr << "  For IPv6, try:n";
std::cerr << "    receiver 0::0 ff31::8000:1234n";
return 1;
}
boost::asio::io_service io_service,io_service1;
receiver r(io_service,
boost::asio::ip::address::from_string(argv[1]),
boost::asio::ip::address::from_string(argv[2]));
receiver r1(io_service1,
boost::asio::ip::address::from_string(argv[1]),
boost::asio::ip::address::from_string(argv[2]));   

boost::thread thread1{[&io_service](){ io_service.run(); }}; 
boost::thread thread2{[&io_service1](){ io_service1.run(); }};
thread1.join();
thread2.join();
//  boost::asio::io_service io_service;
//   receiver r(io_service,
//   boost::asio::ip::address::from_string(argv[1]),
//   boost::asio::ip::address::from_string(argv[2]));
//  for (int i = 0; i < 2; ++i) {
//     boost::thread z(boost::bind(&boost::asio::io_service::run, &io_service));
//   z.join();
// }
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "n";
}
return 0;
}    

我已经更新了整个程序。 此代码工作正常,但无法将线程代码放入循环中。 我能够手动创建多个接收器(线程(,但无法使用循环创建多个线程。

我已经更新了整个程序。 此代码工作正常,但无法将线程代码放入循环中。 我能够手动创建多个接收器(线程(,但无法使用循环创建多个线程。

你没有展示receiver类,我想它看起来像

struct receiver
{
receiver(boost::asio::io_service& io, ...)
: io(io), ... 
{
}
boost::asio::io_service& io;
};

这里的关键点是receiver存储对io_service对象的引用。io_service是 asio 中许多无法复制/移动的类之一。如果类包含引用,则编译器无法为该类生成复制/移动操作。此外,receiver没有默认构造函数。例如,这些限制结果不能用于存储接收器vector<receiver>- 在循环中创建对象时会很有用。

解决此问题的简单方法是使用(智能(指针 -shared_ptr

如果io_service未在receiver实例之间共享,则可以将其作为receiver的成员变量:

struct receiver {
receiver(boost::asio::ip::address, boost::asio::ip::address)
: th(boost::bind(&boost::asio::io_service::run,&ioService))
{     // ^^^ thread is started here
}
~receiver() {
if (th.joinable())
th.join();
}
boost::asio::io_service ioService;
boost::thread th;
};

main可以减少到:

try {
if (argc != 3) {
std::cerr << "Usage: receiver <listen_address> <multicast_address>n";
std::cerr << "  For IPv4, try:n";
std::cerr << "    receiver 0.0.0.0 239.255.0.1n";
std::cerr << "  For IPv6, try:n";
std::cerr << "    receiver 0::0 ff31::8000:1234n";
return 1;
}
std::vector<boost::shared_ptr<receiver>> receivers;
for (int i = 0; i < 2; ++i) 
{
receivers.push_back(boost::make_shared<receiver>(boost::asio::ip::address::from_string(argv[1]),
boost::asio::ip::address::from_string(argv[2])));
}
}
catch (std::exception& e) {
std::cerr << "Exception: " << e.what() << "n";
}

编译

最新更新