19.3 Boost Asio 多线程通信

简介: 多线程服务依赖于两个通用函数,首先`boost::bind`提供了一个高效的、简单的方法来创建函数对象和函数对象适配器,它的主要功能是提供了一种将函数和它的参数绑定到一起的方法,这种方法可以将具有参数的成员函数、普通函数以及函数对象转化为不带参数的函数对象。当参数绑定后则下一步就需要使用多线程功能,Boost库中提供了`boost::thread`库,`boost::thread`可以用于创建线程、启动线程、等待线程执行结束以及线程间通信等多种操,有了这两个关键库那么我们只需要`accept.accept(*sock)`等待套接字上线,当有套接字上线后则自动创建`MyThread`子线程,

多线程服务依赖于两个通用函数,首先boost::bind提供了一个高效的、简单的方法来创建函数对象和函数对象适配器,它的主要功能是提供了一种将函数和它的参数绑定到一起的方法,这种方法可以将具有参数的成员函数、普通函数以及函数对象转化为不带参数的函数对象。

当参数绑定后则下一步就需要使用多线程功能,Boost库中提供了boost::thread库,boost::thread可以用于创建线程、启动线程、等待线程执行结束以及线程间通信等多种操,有了这两个关键库那么我们只需要accept.accept(*sock)等待套接字上线,当有套接字上线后则自动创建MyThread子线程,使用该子线程维持会话,首先是服务端实现代码。

#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>

using namespace boost::asio;

std::string addr = "127.0.0.1";

// 创建子线程
void MyThread(boost::shared_ptr<ip::tcp::socket> socket)
{
   
   
  // 获取当前IP信息
  std::string local_address = socket->local_endpoint().address().to_string();
  while (true)
  {
   
   
    try
    {
   
   
      if (addr == local_address)
      {
   
   
        char data[512];
        size_t len = socket->read_some(buffer(data));
        std::cout << data << std::endl;
      }
    }
    catch (boost::system::system_error e)
    {
   
   
      return;
    }
  }
}

int main(int argc, char* argv[])
{
   
   
  typedef boost::shared_ptr<ip::tcp::socket> socket_ptr;
  io_service service;

  // 绑定IP与端口地址
  ip::tcp::endpoint ep(ip::tcp::v4(), 6666);
  ip::tcp::acceptor accept(service, ep);

  while (true)
  {
   
   
    socket_ptr sock(new ip::tcp::socket(service));

    // 侦听套接字
    accept.accept(*sock);

    // 绑定套接字参数
    boost::function0<void> function = boost::bind(MyThread, sock);

    // 创建新的子线程
    boost::thread threading(function);
  }

  system("pause");
  return 0;
}

客户端代码如下所示,由于客户端无需实现多线程所以代码中只需要简单的调用socket.connect()链接到服务端,并调用write_some发送一条消息即可,代码如下图所示;

#include <iostream>
#include <string>
#include <boost/asio.hpp>

using namespace boost::asio;

int main(int argc, char *argv[])
{
   
   
  io_service io_service;
  ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 6666);
  ip::tcp::socket socket(io_service);

  // 链接到服务端
  socket.connect(ep);

  char buffer[1024] = "hello lyshark";

  socket.write_some(boost::asio::buffer(buffer, 1024));

  system("pause");
  return 0;
}

运行上方服务端代码,然后开启三个客户端代码,读者可自行观察通信状态,此时三个客户端均实现了输出,如下图所示;

目录
相关文章
|
2月前
|
Java
实现Java多线程中的线程间通信
实现Java多线程中的线程间通信
|
3月前
|
Java 程序员
从菜鸟到大神:JAVA多线程通信的wait()、notify()、notifyAll()之旅
【6月更文挑战第21天】Java多线程核心在于wait(), notify(), notifyAll(),它们用于线程间通信与同步,确保数据一致性。wait()让线程释放锁并等待,notify()唤醒一个等待线程,notifyAll()唤醒所有线程。这些方法在解决生产者-消费者问题等场景中扮演关键角色,是程序员从新手到专家进阶的必经之路。通过学习和实践,每个程序员都能在多线程编程的挑战中成长。
41 6
|
3月前
|
Java
Java Socket编程与多线程:提升客户端-服务器通信的并发性能
【6月更文挑战第21天】Java网络编程中,Socket结合多线程提升并发性能,服务器对每个客户端连接启动新线程处理,如示例所示,实现每个客户端的独立操作。多线程利用多核处理器能力,避免串行等待,提升响应速度。防止死锁需减少共享资源,统一锁定顺序,使用超时和重试策略。使用synchronized、ReentrantLock等维持数据一致性。多线程带来性能提升的同时,也伴随复杂性和挑战。
76 0
|
3月前
|
安全 Java
JAVA多线程通信新解:wait()、notify()、notifyAll()的实用技巧
【6月更文挑战第20天】Java多线程中,`wait()`, `notify()`和`notifyAll()`用于线程通信。在生产者-消费者模型示例中,它们确保线程同步。`synchronized`保证安全,`wait()`在循环内防止虚假唤醒,`notifyAll()`避免唤醒单一线程问题。关键技巧包括:循环内调用`wait()`,优先使用`notifyAll()`以保证可靠性,以及确保线程安全和正确处理`InterruptedException`。
38 0
|
30天前
|
存储 安全 Java
【多线程面试题 七】、 说一说Java多线程之间的通信方式
Java多线程之间的通信方式主要有:使用Object类的wait()、notify()、notifyAll()方法进行线程间协调;使用Lock接口的Condition的await()、signal()、signalAll()方法实现更灵活的线程间协作;以及使用BlockingQueue作为线程安全的队列来实现生产者和消费者模型的线程通信。
|
3月前
|
Java 开发者
线程通信的方法和实现技巧详解
线程通信的方法和实现技巧详解
|
2月前
|
Java
实现Java多线程中的线程间通信
实现Java多线程中的线程间通信
|
2月前
|
消息中间件 安全 Java
Java中的线程间通信详解
Java中的线程间通信详解
|
2月前
|
消息中间件 Python
线程通信
【7月更文挑战第1天】
22 2
|
2月前
|
Java
线程间通信的几种方法
线程间通信的几种方法